[英]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.