I would like to know if the two approaches are equivalent:
Approach 1
class A:
toto = 1
vs, Approach 2:
class A:
def __new__(cls, *args, **kwargs):
cls.toto = 1
return super().__new__(cls, *args, **kwargs)
To me they look the same. Especially, printing dir(A)
gives the same result:
['__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
...
'toto']
Thanks
CodePudding user response:
No, these are not equivalent.
Approach 1 only sets the class variable once. Approach 2 sets it possibly 0 or many times, as many times as you instantiate an A
object.
Consider the simplest case:
>>> class A:
... toto = 1
...
>>> print(A.toto)
1
However:
>>> class A:
... def __new__(cls, *args, **kwargs):
... cls.toto = 1
... return super().__new__(cls, *args, **kwargs)
...
>>> print(A.toto)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'A' has no attribute 'toto'
Now consider a more complicated case:
>>> class A:
... toto = 1
...
>>> a = A()
>>> A.toto = 42
>>> a = A()
>>> print(A.toto)
42
However:
>>> class A:
... def __new__(cls, *args, **kwargs):
... cls.toto = 1
... return super().__new__(cls, *args, **kwargs)
...
>>> a = A()
>>> A.toto = 42
>>> a = A()
>>> print(A.toto)
1