
dataclasses 【數據 Class】
簡介
dataclasses module 用於向用戶定義的 Class 新增 special methods (特殊方法),例如:__init__ 或 __repr__。
使用 Dataclasses 的主要優點是在建立 Class 時減少 Boilerplate code,特別是那些主要儲存數據,但沒有太多行為 (方法) 的 Class。
Dataclasses 自動向 Class 加入 special methods,包括:__init__、__repr__ 和 __eq__。 這些 special methods 手動編寫通常很乏味,特別是對於具有許多屬性的 Class。如果需要,也可以自定義和微調這些方法的行為。
數據類的裝飾器是 @dataclasses.dataclass。 這是一個簡單的例子:
import dataclasses
@dataclasses.dataclass
class Point:
x: int
y: int
# Create instances of Point (__init__)
p1 = Point(2, 3)
p2 = Point(2, 3)
p3 = Point(3, 4)
# Demonstrates __repr__
print(p1) # Output: Point(x=2, y=3)
# Demonstrates __eq__
print(p1 == p2) # Output: True
print(p1 == p3) # Output: FalseClass Point 有兩個 fields x 和 y,這 2 個 fields 都應該是 int。
@dataclass 自動加入一個以 x 和 y 作為參數的 __init__ 方法,一個返回物件的字串表示形式的 __repr__ 方法,以及一個 __eq__ 方法,允許根據 Point 的兩個實例的 x 屬性和 y 屬性來比較它們的相等性。
Field
在 Python Dataclasses 的 context 中,field 是綁定到 Class 的變數,並且該 class 的每個實例都將具有其自己的單獨的 field 副本,來存儲特定於實例的狀態。
在傳統的物件導向術語中,這些通常被稱為 "attributes" or "properties"。Dataclasses 中的 fields 直接在 Class 中定義,並且可以指定它們的類型和預設值。
在此範例中,name 和 age 是 Person class 的 fields。
name field 應為 str,age field 應為 int,預設值為 0。每個 Person 實例都有自己的 name 和 age fields。
@dataclass
@dataclass 用於生成的 special methods,然後新增到 Class 中。
當 @dataclass 應用於 Class 時,它會掃描該 Class 的 fields。 在這種情況下,fields 是包含類型註釋的 Class-level 變數。
init
是否將生成 __init__ 方法。
如果 Class 已經定義了 __init__,則忽略此參數。
repr
是否將生成 __repr__ 方法。
生成的 repr String 將包含 Class 名稱以及每個 field 的名稱,按照它們在 Class 中定義的順序排列。 不包括標記為從 repr 中排除的 fields 。如果 Class 已經定義了 __repr__,則忽略此參數。
eq
是否將生成 __eq__ 方法。
此方法按順序比較 Class,僅當它們對應的 fields 相等時,該 Class 的兩個實例才會被比較為相等。如果 Class 已經定義了 __eq__ ,則忽略此參數。
order
是否將生成 __lt__ (小於)、__le__ (小於或等於)、__gt__ (大於) 和 __ge__ (大於或等於) 方法。
這些使得 Class 的實例可排序且具有可比性。如果 field's type 不支援比較,這將引發 TypeError。如果 Class 已經定義了 __lt__、__le__、__gt__ 和 __ge__ 中的任何一個,則會引發 TypeError。
unsafe_hash
如果為 True, 會強制生成 __hash__ 方法,但不建議這樣做,因為它違反了 Python's object model,其中 mutable 物件是 unhashable。
如果為 False,則根據 eq 和 frozen 的設置方式生成 __hash__ 方法。
frozen
在實例建立後,指派 fields 將會引發 Exception。
類似於其他語言中的唯讀 (凍結;frozen) 數據類型,就像 Tuple 一樣。如果 Class 中定義了 __setattr__ 或 __delattr__,則會引發 TypeError。
match_args
kw_only
slots
weakref_slot
您不能在 Class 中同時擁有顯式 __hash__ 方法並設置 unsafe_hash=True;這將導致 TypeError。
範例 – unsafe_hash (參數)
field()
該函數用於自定義 Data class 中的各個 fields。就像指定了預設值本身一樣。
default
Field 的預設值。
default_factory
為 field 提供預設值的零參數函數,當該 field 需要預設值時將調用。 如果同時指定了 default 和 default_factory,則會引發 TypeError。
init
Field 將作為參數包含在生成的 __init__ 方法中。
repr
Field 將包含在生成的 __repr__ 方法,返回的 String 中。
hash
如果為 True,則該 field 包含在生成的 __hash__ 方法中。
如果為 None (預設值),則使用 compare
compare
Field 將包含在生成的 __eq__, __gt__... 方法中。
metadata
將值包裝在 MappingProxyType() 中,以使其唯讀,並在 field 物件上公開。 它主要用於第三方擴展,Data Classes 本身不使用。
kw_only
範例 – 基礎
Data class Employee 有兩個 fields name 和 age,這兩個 fields 都具有使用 dataclasses.field() 指定的預設值。
default_factory 參數: 當您想要生成每次都應該是新物件的預設值時,default_factory 非常有用。(例如:空 List 或當前時間戳)
repr 參數: color field 從 __init__, __repr__ 方法中排除。因此在建立 Point 實例時不需要提供它,在打印 Point 物件時不包括它。
範例 – Mutable 物件
如果 field 是 mutable (例如: List, Dictionary),並且您為其提供預設值,則應該使用 default_factory 來提供一個函數,該函數在每次創建新實例時生成新值。 這避免了在多個實例之間共享相同的可變的值。
fields()
fields(class_or_instance) 獲取為特定 Dataclasses 或 Dataclass 實例定義的每個 Field 物件的 metadata。
透過使用 fields(),我們可以對程式碼中的 Dataclasses 進行更詳細的控制和理解。 這對於大量使用 Dataclasses 的複雜程序或 libraries 特別有用。
執行結果:
範例 – 基礎
執行結果:
asdict()
asdict(obj, *, dict_factory=dict) 每個 Dataclass fields 都轉換為 Dictionary,作為 name: value pairs。
透過 dict_factory,將 Dataclass obj 轉換為 dict。(deep copy)
範例 – 具有複雜 field 類型的 Dataclass
執行結果:
collections.OrderedDict 保證 fields 的顯示順序與 Dataclass 中定義的順序相同。
執行結果:
範例 – shallow_copy(obj)
asdict() 方法創建一個 deep copy,它比 shallow copy 的計算量更大,特別是對於大型 Dataclasses。
如果您知道不需要修改 Dataclass 中的任何物件,並且只需要它的簡單 dictionary 表示形式,則 shallow_copy(obj) 可能會更有效。
或者,如果您想要維護 dataclass 實例,您可能需要使用 shallow_copy(obj)。
astuple()
astuple(obj, *, tuple_factory=tuple) 每個 Dataclass fields 都轉換為 Tuple。透過 dict_factory,將 Dataclass obj 轉換為 tuple。
Last updated
Was this helpful?