Why new Python 2.5 feature "class C()" return old-style class ?

A

Aahz

Em Ter, 2006-04-11 às 07:17 -0700, Aahz escreveu:

Why should a newbie use an old-style class?

Because that's the default. Because lots of existing code still uses
classic classes, so you need to learn them anyway. Because you can't use
new-style classes in code intended for 2.1 or earlier; because of the
changes made in 2.3, I don't particularly recommend new-style classes for
2.2. Because even the second edition of _Learning Python_ (targeted at
Python 2.3) doesn't cover new-style classes much, so I'm certainly not
alone in believing that new-style classes are better avoided for newbies.
 
A

Aahz

Aahz a écrit :

Perhaps not *officially* yet...

Not even unofficially. The point at which we have deprecation is when
PEP8 gets changed to say that new-style classes are required for
contributions.
 
B

Bruno Desthuilliers

Wildemar Wildenburger a écrit :
I'm surprised ...
So there will be two (in most cases subtly) different classes of classes
(so to speak) for all eternity?

Why is that? Do classic classes have some advantage over new style ones?
If so, what are they?

I'm afraid the only advantage is that they save you a few keystrokes !-)
 
P

Petr Prikryl

Bruno said:
Aahz a écrit : [...]
Please repeat this 101 times each morning:
"thou shall not use old-style classes for they are deprecated".
Classic classes are *NOT* deprecated.
Perhaps not *officially* yet...

Not even unofficially. The point at which we have deprecation is when
PEP8 gets changed to say that new-style classes are required for
contributions.

My question: Could the old classes be treated in
a new Python treated as new classes with "implicit"
base object? (I know the Zen... ;-)

Example: I use usually a very simple classes. When I add
"(object)" to my class definitions, the code continues to
works fine -- plus I have new features to use.
Why this cannot be done automatically? What could
be broken in the old code if it was threated so?

Thanks for explanation,
pepr
 
R

Robert Kern

Petr said:
...
Bruno said:
Aahz a �crit :
[...]
Please repeat this 101 times each morning:
"thou shall not use old-style classes for they are deprecated".

Classic classes are *NOT* deprecated.

Perhaps not *officially* yet...

Not even unofficially. The point at which we have deprecation is when
PEP8 gets changed to say that new-style classes are required for
contributions.

My question: Could the old classes be treated in
a new Python treated as new classes with "implicit"
base object? (I know the Zen... ;-)

Example: I use usually a very simple classes. When I add
"(object)" to my class definitions, the code continues to
works fine -- plus I have new features to use.
Why this cannot be done automatically? What could
be broken in the old code if it was threated so?

Method resolution order in class hierarchies that have multiple inheritance.

--
Robert Kern
(e-mail address removed)

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
W

Wildemar Wildenburger

Petr said:
My question: Could the old classes be treated in
a new Python treated as new classes with "implicit"
base object? (I know the Zen... ;-)

Example: I use usually a very simple classes. When I add
"(object)" to my class definitions, the code continues to
works fine -- plus I have new features to use.
Why this cannot be done automatically? What could
be broken in the old code if it was threated so?

Thanks for explanation,
pepr
Well, apparently this is exactly whats going to happen in the future,
but not until Python 3.0.
Simple as that.

But I guess I'll just keep adding the (object) appendix even after that,
so all my class definitions get syntax highlighting. Also it clarifies
"what the score is" (to paraphrase Bender).

wildemar
 
C

Christophe

Aahz a écrit :
Because that's the default. Because lots of existing code still uses
classic classes, so you need to learn them anyway. Because you can't use
new-style classes in code intended for 2.1 or earlier; because of the
changes made in 2.3, I don't particularly recommend new-style classes for
2.2. Because even the second edition of _Learning Python_ (targeted at
Python 2.3) doesn't cover new-style classes much, so I'm certainly not
alone in believing that new-style classes are better avoided for newbies.

Well, old-style classes are perfect to confuse the newbie. After all,
there's nothing like adding a "property" in a class and wondering why
it does not work as expected.

What would be a language without horrible pitfalls ? Newbies would have
it easy and they have no right for an easy language !
 
F

Fredrik Lundh

Wildemar said:
But I guess I'll just keep adding the (object) appendix even after that,
so all my class definitions get syntax highlighting.

why are you using an IDE that doesn't understand Python syntax ?

</F>
 
A

Aahz

...

My question: Could the old classes be treated in a new Python treated
as new classes with "implicit" base object? (I know the Zen... ;-)

Example: I use usually a very simple classes. When I add "(object)" to
my class definitions, the code continues to works fine -- plus I have
new features to use. Why this cannot be done automatically? What could
be broken in the old code if it was threated so?

Method resolution order is the primary up-front difference, but
introspective code can also have problems. If you're tired of adding
"(object)", put

__metaclass__ = type

at the top of your modules.
 
A

Alex Martelli

Aahz said:
Method resolution order is the primary up-front difference, but
introspective code can also have problems. If you're tired of adding

The crucial difference between the old-style classes and the new ones is
about how Python lookups special methods. On an instance of an
old-style class, the lookup is on the instance itself:
zap

while on new-style classes, the lookup is ONLY on the class:
<__main__.new object at 0x51a4b0>


The change is in fact a very important improvement, but it badly breaks
backwards compatibility, which explains why it can't be applied
automatically (within the 2.* line).


Alex
 
A

Aahz

The crucial difference between the old-style classes and the new ones
is about how Python lookups special methods.

Right. Thanks! I don't actually use new-style classes much myself, so
I forgot about that one. (And I needed it for the draft that's due
today...)
 
A

Alex Martelli

Aahz said:
Right. Thanks! I don't actually use new-style classes much myself, so
I forgot about that one. (And I needed it for the draft that's due
today...)

Glad to have been of help, then! BTW, I use new-style classes almost
exclusively (except when maintaining legacy code, or, up to 2.4, for
exceptions)...


Alex
 
W

Wildemar Wildenburger

Fredrik said:
why are you using an IDE that doesn't understand Python syntax ?

</F>

Because I don't like using a whole new editor for every new language I'm
using (as you would not use a new hammer for each nail) and jedit just
plain rocks. I guess it could be made to recognize class statements ...
but its python mode works well enough, so I'll rather stick to that and
create python magic.

ok, on to the next useless post ... ;)
wildemar
 
A

Ant

(OT) I don't have the same issue with Syntax highlighting, and I use
jEdit as my main Python editor (Though some of the dedicated Python
IDE's have some nice refactoring/code completion stuff, none has the
raw editing power of jEdit).

I'm using jEdit 4.3 pre3 - though I don't recall any problems with 4.2
(and it was only a week ago I changed). The Jython plugin enables
Structure browsing if you haven't already got it installed.
 
W

Wildemar Wildenburger

Ant said:
(OT) I don't have the same issue with Syntax highlighting, and I use
jEdit as my main Python editor (Though some of the dedicated Python
IDE's have some nice refactoring/code completion stuff, none has the
raw editing power of jEdit).
Could be I got a customized python.xml file when I started ... maybe
I'll have a look.
I'm using jEdit 4.3 pre3 - though I don't recall any problems with 4.2
(and it was only a week ago I changed).
I'm cautious on the pre's ... how much of an improvement is it (feature-
and otherwise)?
The Jython plugin enables
Structure browsing if you haven't already got it installed
Really? I got it with the JPyDebug ... but perhaps that includes Jython.
I'll be looking into Jython soon, as I could use a plugin (for AGAST)
and I'm not learning Java just for that!

wildemar
 
B

Bengt Richter

is meant by whom, and according to what rationale?
Because it it consistent with passing an empty bases-tuple to type,
which is where a non-empty bases-tuple goes. (See more on metaclass logic below).
+1


It does. The statement "class X():" imply there's no superclass, so it
definitiveley should behave the same as "class X:".
I'm not sure what you mean by "no superclass," comparing
[QUOTE= said:
>>> class Y(object): pass ...
>>> y = Y()
>>> type(y).mro()
[/QUOTE]
[<class '__main__.Y'>, <type 'object'>]


The way I look at it, in new-style-capable Python,

class X: pass

is really effectively sugar for

class X: __metaclass__ = types.ClassType

and
class X(bases): pass

is sugar for

class X(bases): __metaclass__ = type

so
class X(): pass

ought to be sugar for

class X(): __metaclass__ = type

I.e., "old-style classes" really inherit methods from a metaclass that overrides
the methods of object, so that new-style descriptor logic can be tweaked to provide the
old behaviors for classes not having type as metaclass.
and expliciteness could sometimes be
sacrified to simplify the life of developer: ex "abcd"[0:3] ->
"abcd"[:3].

Here there's no ambiguity.
And for newbies, the somewhat magic behavior of the "object" superclass
is not so clear even that it is very explicit.

There's no magic involved here. And I really doubt that having
inconsistant behaviour for "class X():" wrt/ "class X:" will help here.
Again, IMO any bases-tuple including empty should be sugar for __metaclass__ = type, i.e.,

class X(): pass

should be consistent with the empty parens in

X = type("X",(),{}),

not with the backwards-compatibility cleverness (really) of effectively
switching default metaclass to

X = types.ClassType("X",(),{})

using an empty and valid base class tuple as a flag for the switcheroo. Note that the code
erroneously creates an empty tuple for class X:pass, as if it were class X():pass.

(IMO the proper way to indicate the you don't have a tuple is to use None or some other sentinel,
not abuse a perfectly legal tuple value).
1 0 LOAD_CONST 0 ('X') <<--+-- ought to be LOAD_CONST 0 (None)
3 BUILD_TUPLE 0 <<--'
6 LOAD_CONST 1 (<code object X at 02EE7EA0, file "", line 1>)
9 MAKE_FUNCTION 0
12 CALL_FUNCTION 0
15 BUILD_CLASS
16 STORE_NAME 0 (X)
19 LOAD_CONST 2 (None)
22 RETURN_VALUE

vs code for class x(something):pass
1 0 LOAD_CONST 0 ('X')
3 LOAD_NAME 0 (object)
6 BUILD_TUPLE 1
9 LOAD_CONST 1 (<code object X at 02EFB9A0, file "", line 1>)
12 MAKE_FUNCTION 0
15 CALL_FUNCTION 0
18 BUILD_CLASS
19 STORE_NAME 1 (X)
22 LOAD_CONST 2 (None)
25 RETURN_VALUE

IMO generating an empty tuple for class X():pass is a natural variation of the immediately above.
What is un-natural is using an empty tuple as a logical flag for old-style classes (implementing
the latter by selecting types.ClassType as the metaclass instead of type)
for what would othewise work perfectly normally with the default metaclass of type.

Code generation would need to provide something other than an empty tuple
on the stack for class X:pass (IWT None would work?) as the logic flag for old-style classes,
and build_class in ceval.c would have to be changed to recognize
the new flag value (None?) for calling types.ClassType,
and pass tuples (including empty) through to type.
You should.
so for now put

__metaclass__ = type

once at the top of your module source, and all your

class X:
...

will be interpreted as

class X:
__metaclass__ = type
...

instead of implicitly as

class X:
__metaclass__ = types.ClassType
...
Please repeat this 101 times each morning:
"thou shall not use old-style classes for they are deprecated".

(snip)


It's mostly a good way to add inconsistency and confusion to a situation
that's already confusing enough for newbies.
I don't agree with your idea of inconsistency.

IMO it would be better to explain that a legal basetuple value (empty tuple) is currently
being abused as a logical flag to call types.ClassType(clsname, basestuple, clsdict)
instead of type(clsname, basestuple, clsdict), and explain that it will be corrected, so that
class X():pass will now call the latter, consistent with class X(bases):pass.

Bottom line: IMO class C():pass should create a new-style class,
and the parens serve well as a reminder of which kind it is, whether empty or not,
until py3k.

I.e., make it easy for newbies: parens means new-style, no parens means old-style, until py3k.

Pontificating pushes my counter-pontificating button; that's the only explanation
I have for doing this. I was going to stop wasting time, but find myself
unable as yet fully to abandon scanning clp and python-dev ;-/

Regards,
Bengt Richter
 
P

Paul Boddie

Christophe said:
Aahz a écrit :

Well, old-style classes are perfect to confuse the newbie. After all,
there's nothing like adding a "property" in a class and wondering why
it does not work as expected.

Well, for years everyone joked about Java's "public static void main"
business - confusing boilerplate for newbies, they said - but apart
from various deep runtime-dependent arguments, I can't see how "class
something(object)" is any less forgivable, especially in a teaching
environment where you've just explained that "object" and "instance"
are mostly interchangeable terms for something made from a class.

And to make the "guard of shame" (the opposite of a guard of honour)
complete in this sorry tale, it should be pointed out that they don't
make you write "class Something extends Object" all over the place in
Java, or at least not when I last wrote any Java code. Something to
think about for Python 3000 in the context of reaching a wider
audience, I suppose.
What would be a language without horrible pitfalls ? Newbies would have
it easy and they have no right for an easy language !

;-) Or were you being serious? :-O

Paul
 
B

Bengt Richter

]
(IMO the proper way to indicate the you don't have a tuple is to use None or some other sentinel,
not abuse a perfectly legal tuple value).

1 0 LOAD_CONST 0 ('X') <<--+-- ought to be LOAD_CONST 0 (None)
Oops, leave the 'X' of course, just replace the next line
3 BUILD_TUPLE 0 <<--'
6 LOAD_CONST 1 (<code object X at 02EE7EA0, file "", line 1>)
9 MAKE_FUNCTION 0
12 CALL_FUNCTION 0
15 BUILD_CLASS
16 STORE_NAME 0 (X)
19 LOAD_CONST 2 (None)
22 RETURN_VALUE

vs code for class x(something):pass

1 0 LOAD_CONST 0 ('X')
3 LOAD_NAME 0 (object)
6 BUILD_TUPLE 1
9 LOAD_CONST 1 (<code object X at 02EFB9A0, file "", line 1>)
12 MAKE_FUNCTION 0
15 CALL_FUNCTION 0
18 BUILD_CLASS
19 STORE_NAME 1 (X)
22 LOAD_CONST 2 (None)
25 RETURN_VALUE

Regards,
Bengt Richter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top