Le Fri, 12 Jun 2009 22:37:17 +1000, Lie Ryan <lie.1...@gmail.com> s'exprima ainsi:
> spir wrote: > > Hello, > > > > I have (again) some issue using __new__. > > What I need is basically to catch an object creation and yield an object > > of an alternate type, when a condition is met. > > > > Basically, the outline looks like: > > > > class Normal(object): > > def __new__(cls, arg): > > if cond(arg): > > # <yield instance of Special> > > # expression is simply: Special(arg) > > # must be __init__ialised ! > > > > # Conceptually, nothing to change: > > # <yield instance of Normal> > > # must be __init__ialised ! > > > > But I got issues in both cases: > > * cannot find how to get Special objects initialised > > * cannot find how to return Normal object > > roughly like this: > > >>> class Special(object): > ... def __init__(self, arg): > ... self.arg = arg > ... > >>> class Normal(object): > ... def __new__(cls, arg): > ... if arg: > ... return Special(arg) > ... else: > ... ret = super(Normal, cls).__new__(cls) > ... ret.__init__(arg) > ... return ret > ... def __init__(self, arg): > ... self.arg = arg > ... 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. 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. 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.) > >>> 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@python.org http://mail.python.org/mailman/listinfo/tutor