On Tue, 11 Apr 2006 16:30:10 +0200, bruno at modulix <[EMAIL PROTECTED]> wrote:
>looping wrote: >> bruno at modulix wrote: >> >>>looping wrote: >>> >>>>Peter Hansen wrote: >>>> >>>> >>>>>Georg Brandl wrote: >>>>> >>>>> >>>>>>class C(): >>>>>> >>>>>>is meant to be synonymous with is meant by whom, and according to what rationale? >>>>>> >>>>>>class C: >>>>>> >>>>>>and therefore cannot create a new-style class. >>>>> >>>>>I think "looping" understands that, but is basically asking why anyone >>>>>is bothering with a change that involves a part of the language that is >>>>>effectively deprecated. In other words, class(): never used to be >>>>>valid, so why make it valid now? 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). >>>>> >>>>>-Peter >>>> >>>> >>>>Exact. >>>>But I think that if we make "class C():" a synonym of "class >>>>C(object):", it will save lot of keystrokes ;-) >>> +1 >>>Since the class statement without superclass actually creates an >>>old-style class, I'd expect the "class MyClass():" variant to behave >>>the same. Sacrifying readability and expliciteness just to save half a >>>dozen keystrokes is not pythonic IMHO. >>> >> >> >> I don't think readability suffer > >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 >>> class X: pass ... >>> x = X() >>> type(x).mro() [<type 'instance'>, <type 'object'>] with >>> class Y(object): pass ... >>> y = Y() >>> type(y).mro() [<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). >>> dis.dis(compile('class X:pass','','exec')) 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 >>> dis.dis(compile('class X(object):pass','','exec')) 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. >> When I write script I don't use new-style class > >You should. > >> cause is bother me to >> type "(object)" when I don't need their features. 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) > >> So this new syntax is a good way to boost their uses without bother >> with compatibility of existing code IMHO. > >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 -- http://mail.python.org/mailman/listinfo/python-list