[Tutor] use of __new__
lie.1296 at gmail.com
Fri Jun 12 19:08:07 CEST 2009
> Le Fri, 12 Jun 2009 22:37:17 +1000,
> Lie Ryan <lie.1296 at gmail.com> s'exprima ainsi:
> Right, thank you. I continued my trials and ended with seemingly working code, close to yours.
> # case pattern is Klass: yield String instead
> if isinstance(pattern,Klass):
> self = String(pattern, numMin,numMax, expression,name)
> #~ self.__init__(pattern, numMin,numMax, expression,name)
> return self
> # else a Repetition
> self = Pattern.__new__(cls,pattern, numMin,numMax, expression,name)
> return self
> I have more questions:
> 1. For the 'normal' (second) case, I read in the docs that __new__ *must* return the new object. This should be done using the supertype's __new__. But you don't do it and it seems to work anyway. In this case, __init__ is (supposed to be) called automagically.
The super(Normal, cls) construct is semantically equivalent to the
supertype on single inheritance cases. There is a bug in my previous
code: I called "ret.__init__(arg)" manually. It is unnecessary to invoke
__init__ for this since ret is an instance of super(Normal, cls) and
python will do automagic __init__ call on it later after "return ret".
> 2. For the special case, as you can see the __init__ line is commented out and it works anyway. While the docs positively assert that __init__ *won't* be called if an object of a different type is returned, it is anyway.
When this statement is run:
self = String(pattern, numMin,numMax, expression,name)
String() is __init__ ed through normal class instantiation (the one we
see everyday), therefore if you or python's automagic invoke __init__
again, __init__ will be called twice (or thrice) as a result
(in short, the mechanism that invoked __init__ in this case is NOT
python's automagic but String() )
> Of course, i checked that init methods are really used in both cases.
> So, how do things _actually_ work?
> (Such confusions are why each time I need __new__ I have to re-learn the real way to use it.)
It seems in this case python is a little bit out-of-character. Python is
being a little bit protective by doing automagic __init__ call and
automagically making __new__ classmethods. Understandable though, since
we can never be sure what could happen if an object's __new__ and
__init__ is never called.
Rule of thumb:
- no need to call __init__ manually for both Normal() nor Special()
>>>>> a = Normal(True)
>>>>> b = Normal(False)
>> generally though, avoid using __new__
>>> (also Normal's supertype has no explicite __new__, but it has an __init__)
>> Haven't tested yet, but that should be no problem as python will use the
>> supertype's supertype's __new__ and at the end of the method resolution
>> order is object.__new__()
> That's what I thought, too.
> Thanks again,
> la vita e estrany
> Tutor maillist - Tutor at python.org
More information about the Tutor