簡體   English   中英

如何僅獲取具有數據類的實例屬性,而不是 class 屬性?

[英]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.bExample.c存在,而Example.aExample.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 屬性。 目的是在 dataclass dataclass()裝飾器運行后, class 屬性將全部包含字段的默認值,就像指定了默認值本身一樣。

這解釋了為什么 c 有一個c屬性,但沒有d 使用default_factory時沒有 class 屬性,因為此默認值是通過在需要默認值時調用 function 動態生成的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM