声明 class 变量是否与在 __new__ 方法中声明它相同?
Does declaring a class variable is the same as declaring it within the __new__ method?
我想知道这两种方法是否等价:
方法一
class A:
toto = 1
对比方法二:
class A:
def __new__(cls, *args, **kwargs):
cls.toto = 1
return super().__new__(cls, *args, **kwargs)
对我来说,它们看起来一样。特别是,打印 dir(A)
会得到相同的结果:
['__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
...
'toto']
谢谢
不,它们不等价。
方法 1 仅设置 class 变量 一次。方法 2 可能将其设置为 0 次或多次,与实例化 A
对象的次数一样多。
考虑最简单的情况:
>>> class A:
... toto = 1
...
>>> print(A.toto)
1
但是:
>>> 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'
现在考虑一个更复杂的情况:
>>> class A:
... toto = 1
...
>>> a = A()
>>> A.toto = 42
>>> a = A()
>>> print(A.toto)
42
但是:
>>> 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
我想知道这两种方法是否等价:
方法一
class A:
toto = 1
对比方法二:
class A:
def __new__(cls, *args, **kwargs):
cls.toto = 1
return super().__new__(cls, *args, **kwargs)
对我来说,它们看起来一样。特别是,打印 dir(A)
会得到相同的结果:
['__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
...
'toto']
谢谢
不,它们不等价。
方法 1 仅设置 class 变量 一次。方法 2 可能将其设置为 0 次或多次,与实例化 A
对象的次数一样多。
考虑最简单的情况:
>>> class A:
... toto = 1
...
>>> print(A.toto)
1
但是:
>>> 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'
现在考虑一个更复杂的情况:
>>> class A:
... toto = 1
...
>>> a = A()
>>> A.toto = 42
>>> a = A()
>>> print(A.toto)
42
但是:
>>> 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