[Tutor] use of __new__

Lie Ryan lie.1296 at gmail.com
Fri Jun 12 19:08:07 CEST 2009


spir wrote:
> 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)
>>>>> a.arg
>> True
>>>>> b.arg
>> 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,
> Denis
> ------
> la vita e estrany
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
> 



More information about the Tutor mailing list