當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


Python dataclasses.dataclass用法及代碼示例

用法:

@dataclasses.dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False)

該函數是一個裝飾器,用於將生成的特殊方法添加到類中,如下所述。

dataclass() 裝飾器檢查類以找到 field s。 field 被定義為具有類型注釋的類變量。除了下麵說明的兩個例外,dataclass() 中的任何內容都不會檢查變量注釋中指定的類型。

所有生成的方法中的字段順序是它們在類定義中出現的順序。

dataclass() 裝飾器將向類添加各種“dunder” 方法,如下所述。如果類中已存在任何添加的方法,則行為取決於參數,如下所述。裝飾器返回調用它的同一個類;沒有創建新的類。

如果 dataclass() 僅用作不帶參數的簡單裝飾器,則它的行為就像它具有此簽名中記錄的默認值一樣。也就是說,dataclass() 的這三種用法是等價的:

@dataclass
class C:
    ...

@dataclass()
class C:
    ...

@dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False)
class C:
   ...

dataclass() 的參數是:

  • init :如果為 true(默認值),將生成 __init__() 方法。

    如果該類已定義 __init__() ,則忽略此參數。

  • repr :如果為 true(默認值),將生成 __repr__() 方法。生成的 repr 字符串將具有類名以及每個字段的名稱和 repr,按照它們在類中定義的順序。不包括標記為從 repr 中排除的字段。例如:InventoryItem(name='widget', unit_price=3.0, quantity_on_hand=10)

    如果該類已定義 __repr__() ,則忽略此參數。

  • eq :如果為 true(默認值),將生成 __eq__() 方法。此方法按順序比較類,就好像它是其字段的元組一樣。比較中的兩個實例必須是相同的類型。

    如果該類已定義 __eq__() ,則忽略此參數。

  • order :如果為真(默認為 False ),將生成 __lt__()__le__()__gt__()__ge__() 方法。這些按順序比較類,就好像它是其字段的元組一樣。比較中的兩個實例必須是相同的類型。如果order 為真且eq 為假,則引發ValueError

    如果該類已經定義了任何 __lt__()__le__()__gt__()__ge__() ,則引發 TypeError

  • unsafe_hash:如果是False(默認),則根據eqfrozen的設置方式生成__hash__()方法。

    __hash__() 由內置的 hash() 使用,並且在將對象添加到哈希集合(例如字典和集合)時使用。擁有__hash__() 意味著該類的實例是不可變的。可變性是一個複雜的屬性,它取決於程序員的意圖、__eq__() 的存在和行為,以及 dataclass() 裝飾器中的 eqfrozen 標誌的值。

    默認情況下,dataclass() 不會隱式添加 __hash__() 方法,除非這樣做是安全的。它也不會添加或更改現有的明確定義的__hash__() 方法。設置類屬性 __hash__ = None 對 Python 具有特定含義,如 __hash__() 文檔中所述。

    如果 __hash__() 沒有明確定義,或者如果它設置為 None ,那麽 dataclass() may 添加一個隱式 __hash__() 方法。盡管不推薦,但您可以強製 dataclass() 使用 unsafe_hash=True 創建 __hash__() 方法。如果您的類在邏輯上是不可變的,但仍然可以發生變異,則可能會出現這種情況。這是一個專門的用例,應該仔細考慮。

    以下是管理 __hash__() 方法的隱式創建的規則。請注意,您不能在數據類中同時使用顯式 __hash__() 方法並設置 unsafe_hash=True ;這將導致 TypeError

    如果 eqfrozen 都為真,默認情況下 dataclass() 將為您生成 __hash__() 方法。如果 eq 為真且 frozen 為假,則 __hash__() 將設置為 None ,將其標記為不可散列(因為它是可變的)。如果 eq 為假,__hash__() 將保持不變,這意味著將使用超類的 __hash__() 方法(如果超類是 object ,這意味著它將回退到基於 id 的散列)。

  • frozen :如果為真(默認為 False ),分配給字段將產生異常。這模擬隻讀凍結實例。如果在類中定義了__setattr__()__delattr__(),則引發TypeError。請參閱下麵的討論。

  • match_args :如果為真(默認為 True ),將從參數列表創建 __match_args__ 元組到生成的 __init__() 方法(即使沒有生成 __init__(),見上文)。如果為 false,或者如果類中已經定義了__match_args__,則不會生成__match_args__

3.10 版中的新函數。

  • kw_only :如果為真(默認值為 False ),則所有字段都將標記為僅限關鍵字。如果字段被標記為僅關鍵字,那麽唯一的影響是在調用 __init__() 時,必須使用關鍵字指定從僅關鍵字字段生成的 __init__() 參數。對數據類的任何其他方麵都沒有影響。有關詳細信息,請參閱參數詞匯表條目。另請參閱KW_ONLY 部分。

3.10 版中的新函數。

  • slots :如果為真(默認為 False ),將生成 __slots__ 屬性並返回新類而不是原始類。如果類中已經定義了__slots__,則引發TypeError

3.10 版中的新函數。

field s 可以選擇使用普通 Python 語法指定默認值:

@dataclass
class C:
    a: int       # 'a' has no default value
    b: int = 0   # assign a default value for 'b'

在此示例中,ab 都將包含在添加的 __init__() 方法中,該方法將定義為:

def __init__(self, a: int, b: int = 0):

TypeError 如果一個沒有默認值的字段跟在一個有默認值的字段後麵,則會引發 TypeError。無論這發生在單個類中還是作為類繼承的結果都是如此。

相關用法


注:本文由純淨天空篩選整理自python.org大神的英文原創作品 dataclasses.dataclass。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。