Why does the .__ new__ object with arguments work fine in Python 2.x and not in Python 3.3+?

Why the following code works fine in Python 2.x and not in Python 3.3+:

class TestA(object): def __new__(cls, e): return super(TestA, cls).__new__(TestB, e) class TestB(TestA): def __init__(self, e): print(self, e) TestA(1) 

Python 2.7.6 output:

 (<__main__.TestB object at 0x7f6303378ad0>, 1) 

Python 3.1.5 output:

 __main__:3: DeprecationWarning: object.__new__() takes no parameters <__main__.TestB object at 0x7f2f69db8f10> 1 

Python 3.2.3 and 3.2.5 output:

 <__main__.TestB object at 0xcda690> 1 

Python 3.3.5 and 3.4.1 output:

 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in __new__ TypeError: object() takes no parameters 
+7
source share
2 answers

object.__new__ always ignored additional arguments and DeprecationWarning , at least since Python 2.6.

The reason you don't see DeprecationWarning in 2.7 and 3.2 is because 2.7 and 3.2 DeprecationWarning were suppressed by default ; if you use python -Wd or PYTHONWARNINGS=default , you will see a warning.

In Python 3.3, DeprecationWarning was converted to an error.

The right way to write code (in any version of Python) is to swallow an additional argument in TestA.__new__ :

 class TestA(object): def __new__(cls, e): return super(TestA, cls).__new__(TestB) 

Since TestB derived from TestA , an additional argument will be passed to TestB.__init__ .

+3
source share

You can move the __init__ function to TestA like this:

 class TestA(object): def __new__(cls, e): return super(TestA, cls).__new__(TestA) def __init__(self, e): print(self, e) TestA(1) 

Please note that TestB is not required.

Please note that the parameter "e" is not specified when the .__ new__ object is called. The new function of the object class only accepts the class as a parameter, and any additional parameters in the overloaded __new__ function (in this case the TestA class) are automatically passed to the constructor function (__init__) of the class passed to the .__ new__ object (which in this case is also TestA).

0
source share

All Articles