Home > Enterprise >  Does declaring a class variable is the same as declaring it within the __new__ method?
Does declaring a class variable is the same as declaring it within the __new__ method?

Time:04-27

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
  • Related