So, I only realised today that __new__
is deprecated for receiving arguments, as of python 2.6 (it isn't mentioned in the documentation, which is also not true in terms of the behavior of __new__
calling __init__
as far as I can see). This means my functional code has started raising warnings, and I want to rid myself of them. But I can't see an elegant way to work around.
I have a bunch of classes that perform optimizations when they are constructed. So I have
class Conjunction(Base):
def __new__(cls, a, b):
if a == True:
return b
elif b == True
return a
else:
return super(Conjunction,cls).__new__(cls, a, b)
And so on (real versions cover lots more cases). So unlike what Guido says in this response (the only reference to it I can find), my __new__
method does use its arguments, and cannot be replaced by an overridden __init__
function.
The best I can do is to split this in two:
def Conjunction(a, b):
if a == True:
return b
elif b == True
return a
else:
return ConjunctionImpl(a, b)
class ConjunctionImpl(Base):
# ...
But that is plain ugly and stinks to high heaven. Am I missing an elegant way to have a class constructor return some arbitrary object based on the constructor parameters it is given?
__new__
is not "deprecated for receiving arguments". What changed in Python 2.6 is that object.__new__
, the __new__
method of the object class, no longer ignores any arguments it's passed. (object.__init__
also doesn't ignore the arguments anymore, but that's just a warning in 2.6.) You can't use object
as the terminating class for your inheritance if you want to pass arguments to __new__
or __init__
.
In order for any code to rely on that behaviour to work in 2.6, you just have to replace object
as the baseclass, using a baseclass that properly accepts the extra arguments and does not pass them along in the calls it makes (using super()
.)
Thomas put me right in his answer, but I should add that the solution in my case was trivial: add a __new__
method to my base class with the lines:
class Base(object):
def __new__(cls, *args, **kws):
instance = super(Base, cls).__new__(cls)
instance.__init__(*args, **kws)
return instance
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With