[英]How to get only instance attributes with dataclasses, not class attributes?
考虑:
from dataclasses import dataclass, field
@dataclass
class Example:
a: int
b: int = 2
c: int = field(default=3)
d: int = field(default_factory=lambda: 4)
令我惊讶的是, Example.b
和Example.c
存在,而Example.a
和Example.d
不存在(是的,我在这里谈论的是 class 属性,而不是实例属性):
try:
print(Example.a)
except AttributeError as e:
print(e)
# AttributeError: type object 'Example' has no attribute 'a'
print(Example.b)
# 2
print(Example.c)
# 3
try:
print(Example.d)
except AttributeError as e:
print(e)
# AttributeError: type object 'Example' has no attribute 'd'
我希望他们都给出一个错误。 我想要的是实例属性,而不是 class 属性。 有时 class 属性也存在的事实似乎是错误的大门。
显然,根据我上面学到的知识,我可以做到以下几点:
from dataclasses import dataclass, field
@dataclass
class Example:
a: int
b: int = field(default_factory=lambda: 2)
c: int = field(default_factory=lambda: 3)
d: int = field(default_factory=lambda: 4)
问题:
1.有没有更清洁的方法来实现这一点? default_factory
的这种用法是否被认为是不可读的?
2. 为什么有人想要一个既是 class 属性又是实例属性的字段?
谢谢!
这在文档中都有解释,尽管它在整个文档中有些分散。
描述可变默认值的部分说
Python 将默认成员变量值存储在 class 属性中。
由于a
没有默认值,因此没有相应的 class 属性。
然后它显示了一个示例:
@dataclass
class D:
x: List = []
def add(self, element):
self.x += element
生成类似于
class D:
x = []
def __init__(self, x=x):
self.x = x
def add(self, element):
self.x += element
请记住,参数默认值是在定义function 时评估的,而不是在调用它时评估的。 所以重新分配Dx
不会改变构造新实例时使用的默认值。 (本节中的示例说明了一个不同的问题:使用默认值创建的所有实例将共享对同一列表的引用;请参阅“Least Astonishment”和 Mutable Default Argument )。
dataclasses.field
的描述说:
如果通过调用
field()
指定了字段的默认值,则该字段的 class 属性将被指定的默认值替换。 如果未提供默认值,则将删除 class 属性。 目的是在 dataclassdataclass()
装饰器运行后, class 属性将全部包含字段的默认值,就像指定了默认值本身一样。
这解释了为什么 c 有一个c
属性,但没有d
。 使用default_factory
时没有 class 属性,因为此默认值是通过在需要默认值时调用 function 动态生成的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.