<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ### 導航 - [索引](../genindex.xhtml "總目錄") - [模塊](../py-modindex.xhtml "Python 模塊索引") | - [下一頁](contextlib.xhtml "contextlib --- Utilities for with-statement contexts") | - [上一頁](warnings.xhtml "warnings --- Warning control") | - ![](https://box.kancloud.cn/a721fc7ec672275e257bbbfde49a4d4e_16x16.png) - [Python](https://www.python.org/) ? - zh\_CN 3.7.3 [文檔](../index.xhtml) ? - [Python 標準庫](index.xhtml) ? - [Python運行時服務](python.xhtml) ? - $('.inline-search').show(0); | # [`dataclasses`](#module-dataclasses "dataclasses: Generate special methods on user-defined classes.") --- 數據類 **源碼:** [Lib/dataclasses.py](https://github.com/python/cpython/tree/3.7/Lib/dataclasses.py) \[https://github.com/python/cpython/tree/3.7/Lib/dataclasses.py\] - - - - - - 這個模塊提供了一個裝飾器和一些函數,用于自動添加生成的 [special method](../glossary.xhtml#term-special-method)s ,例如 [`__init__()`](../reference/datamodel.xhtml#object.__init__ "object.__init__") 和 [`__repr__()`](../reference/datamodel.xhtml#object.__repr__ "object.__repr__") 到用戶定義的類。 它最初描述于 [**PEP 557**](https://www.python.org/dev/peps/pep-0557) \[https://www.python.org/dev/peps/pep-0557\] 。 在這些生成的方法中使用的成員變量使用 [**PEP 526**](https://www.python.org/dev/peps/pep-0526) \[https://www.python.org/dev/peps/pep-0526\] 類型注釋定義。例如這段代碼: ``` @dataclass class InventoryItem: '''Class for keeping track of an item in inventory.''' name: str unit_price: float quantity_on_hand: int = 0 def total_cost(self) -> float: return self.unit_price * self.quantity_on_hand ``` 除其他事情外,將添加 [`__init__()`](../reference/datamodel.xhtml#object.__init__ "object.__init__") ,其看起來像: ``` def __init__(self, name: str, unit_price: float, quantity_on_hand: int=0): self.name = name self.unit_price = unit_price self.quantity_on_hand = quantity_on_hand ``` 請注意,此方法會自動添加到類中:它不會在上面顯示的 `InventoryItem` 定義中直接指定。 3\.7 新版功能. ## 模塊級裝飾器、類和函數 `@``dataclasses.``dataclass`(*\**, *init=True*, *repr=True*, *eq=True*, *order=False*, *unsafe\_hash=False*, *frozen=False*)這個函數是 [decorator](../glossary.xhtml#term-decorator) ,用于將生成的 [special method](../glossary.xhtml#term-special-method) 添加到類中,如下所述。 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 裝飾器檢查類以找到 `field`。 `field` 被定義為具有 [類型標注](../glossary.xhtml#term-variable-annotation) 的類變量。除了下面描述的兩個例外,在 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 中沒有任何內容檢查變量標注中指定的類型。 所有生成的方法中的字段順序是它們在類定義中出現的順序。 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 裝飾器將向類中添加各種“dunder”方法,如下所述。如果類中已存在任何添加的方法,則行為取決于參數,如下所述。裝飾器返回被調用的同一個類;沒有創建新類。 如果 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 僅用作沒有參數的簡單裝飾器,它就像它具有此簽名中記錄的默認值一樣。也就是說,這三種 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 用法是等價的: ``` @dataclass class C: ... @dataclass() class C: ... @dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False) class C: ... ``` [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 的參數有: - `init`: 如果為真值(默認),將生成一個 `__ init__()` 方法。 如果類已定義 `__ init__()` ,則忽略此參數。 - `repr` :如果為真值(默認),將生成一個 [`__repr__()`](../reference/datamodel.xhtml#object.__repr__ "object.__repr__") 方法。 生成的 repr 字符串將具有類名以及每個字段的名稱和 repr ,按照它們在類中定義的順序。不包括標記為從 repr 中排除的字段。 例如:`InventoryItem(name='widget', unit_price=3.0, quantity_on_hand=10)`。 如果類已定義 [`__repr__()`](../reference/datamodel.xhtml#object.__repr__ "object.__repr__") ,則忽略此參數。 - `eq` :如果為true(默認值),將生成 [`__eq__()`](../reference/datamodel.xhtml#object.__eq__ "object.__eq__") 方法。此方法將類作為其字段的元組按順序比較。比較中的兩個實例必須是相同的類型。 如果類已定義 [`__eq__()`](../reference/datamodel.xhtml#object.__eq__ "object.__eq__") ,則忽略此參數。 - `order` :如果為真值(默認為 `False` ),則 [`__lt__()`](../reference/datamodel.xhtml#object.__lt__ "object.__lt__") 、 `__ le__()` 、 [`__gt__()`](../reference/datamodel.xhtml#object.__gt__ "object.__gt__") 和 [`__ge__()`](../reference/datamodel.xhtml#object.__ge__ "object.__ge__") 方法將生成。 這將類作為其字段的元組按順序比較。比較中的兩個實例必須是相同的類型。如果 `order` 為真值并且 `eq` 為假值 ,則引發 [`ValueError`](exceptions.xhtml#ValueError "ValueError") 。 如果類已經定義了 [`__lt__()`](../reference/datamodel.xhtml#object.__lt__ "object.__lt__") 、 [`__le__()`](../reference/datamodel.xhtml#object.__le__ "object.__le__") 、 [`__gt__()`](../reference/datamodel.xhtml#object.__gt__ "object.__gt__") 或者 [`__ge__()`](../reference/datamodel.xhtml#object.__ge__ "object.__ge__") 中的任意一個,將引發 [`TypeError`](exceptions.xhtml#TypeError "TypeError") 。 - `unsafe_hash` :如果為 `False` (默認值),則根據 `eq` 和 `frozen` 的設置方式生成 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 方法。 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 由內置的 [`hash()`](functions.xhtml#hash "hash") 使用,當對象被添加到散列集合(如字典和集合)時。有一個 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 意味著類的實例是不可變的。可變性是一個復雜的屬性,取決于程序員的意圖, [`__eq__()`](../reference/datamodel.xhtml#object.__eq__ "object.__eq__") 的存在性和行為,以及 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 裝飾器中 `eq` 和 `frozen` 標志的值。 默認情況下, [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 不會隱式添加 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 方法,除非這樣做是安全的。 它也不會添加或更改現有的明確定義的 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 方法。 設置類屬性 `__hash__ = None` 對 Python 具有特定含義,如 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 文檔中所述。 如果 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 沒有顯式定義,或者它被設置為 `None` ,那么 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") *可以* 添加一個隱式 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 方法。雖然不推薦,但你可以強制 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 用 `unsafe_hash=True` 創建一個 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 方法。 如果你的類在邏輯上是不可變的但實際仍然可變,則可能就是這種情況。這是一個特殊的用例,應該仔細考慮。 以下是隱式創建 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 方法的規則。請注意,你不能在數據類中都使用顯式的 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 方法并設置 `unsafe_hash=True` ;這將導致 [`TypeError`](exceptions.xhtml#TypeError "TypeError") 。 如果 `eq` 和 `frozen` 都是 true,默認情況下 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 將為你生成一個 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 方法。如果 `eq` 為 true 且 `frozen` 為 false ,則 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 將被設置為 `None` ,標記它不可用(因為它是可變的)。如果 `eq` 為 false ,則 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 將保持不變,這意味著將使用超類的 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 方法(如果超類是 [`object`](functions.xhtml#object "object") ,這意味著它將回到基于id的hash)。 - `frozen` :如果為 true (默認值為 False ),則字段賦值將生成異常。這模擬了只讀的凍結實例。如果 `__setattr __()` 或 [`__delattr__()`](../reference/datamodel.xhtml#object.__delattr__ "object.__delattr__") 在類中定義,則 [`TypeError`](exceptions.xhtml#TypeError "TypeError") 被引發。請參閱下面的討論。 `field`s 可以選擇使用普通的 Python 語法指定默認值: ``` @dataclass class C: a: int # 'a' has no default value b: int = 0 # assign a default value for 'b' ``` 在這個例子中, `a` 和 `b` 都將包含在添加的 [`__init__()`](../reference/datamodel.xhtml#object.__init__ "object.__init__") 方法中,它們將被定義為: ``` def __init__(self, a: int, b: int = 0): ``` 如果沒有默認值的字段跟在具有默認值的字段后,將引發 [`TypeError`](exceptions.xhtml#TypeError "TypeError") 。當這發生在單個類中時,或者作為類繼承的結果時,都是如此。 `dataclasses.``field`(*\**, *default=MISSING*, *default\_factory=MISSING*, *repr=True*, *hash=None*, *init=True*, *compare=True*, *metadata=None*)對于常見和簡單的用例,不需要其他功能。但是,有些數據類功能需要額外的每字段信息。為了滿足這種對附加信息的需求,你可以通過調用提供的 [`field()`](#dataclasses.field "dataclasses.field") 函數來替換默認字段值。例如: ``` @dataclass class C: mylist: List[int] = field(default_factory=list) c = C() c.mylist += [1, 2, 3] ``` 如上所示, `MISSING` 值是一個 sentinel 對象,用于檢測是否提供了 `default` 和 `default_factory` 參數。 使用此 sentinel 是因為 `None` 是 `default` 的有效值。沒有代碼應該直接使用 `MISSING` 值。 [`field()`](#dataclasses.field "dataclasses.field") 參數有: - `default` :如果提供,這將是該字段的默認值。這是必需的,因為 [`field()`](#dataclasses.field "dataclasses.field") 調用本身會替換一般的默認值。 - `default_factory` :如果提供,它必須是一個零參數可調用對象,當該字段需要一個默認值時,它將被調用。除了其他目的之外,這可以用于指定具有可變默認值的字段,如下所述。 同時指定 `default` 和 `default_factory` 將產生錯誤。 - `init` :如果為true(默認值),則該字段作為參數包含在生成的 [`__init__()`](../reference/datamodel.xhtml#object.__init__ "object.__init__") 方法中。 - `repr` :如果為true(默認值),則該字段包含在生成的 [`__repr__()`](../reference/datamodel.xhtml#object.__repr__ "object.__repr__") 方法返回的字符串中。 - `compare` :如果為true(默認值),則該字段包含在生成的相等性和比較方法中( [`__eq__()`](../reference/datamodel.xhtml#object.__eq__ "object.__eq__") , [`__gt__()`](../reference/datamodel.xhtml#object.__gt__ "object.__gt__") 等等)。 - `hash` :這可以是布爾值或 `None` 。如果為true,則此字段包含在生成的 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 方法中。如果為 `None` (默認值),請使用 `compare` 的值,這通常是預期的行為。如果字段用于比較,則應在 hash 中考慮該字段。不鼓勵將此值設置為 `None` 以外的任何值。 設置 `hash=False` 但 `compare=True` 的一個可能原因是,如果一個計算 hash 的代價很高的字段是檢驗等價性需要的,但還有其他字段可以計算類型的 hash 。 即使從 hash 中排除某個字段,它仍將用于比較。 - `metadata` :這可以是映射或 None 。 None 被視為一個空的字典。這個值包含在 `MappingProxyType()` 中,使其成為只讀,并暴露在 [`Field`](#dataclasses.Field "dataclasses.Field") 對象上。數據類根本不使用它,它是作為第三方擴展機制提供的。多個第三方可以各自擁有自己的鍵值,以用作元數據中的命名空間。 如果通過調用 [`field()`](#dataclasses.field "dataclasses.field") 指定字段的默認值,則該字段的類屬性將替換為指定的 `default` 值。如果沒有提供 `default` ,那么將刪除類屬性。目的是在 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 裝飾器運行之后,類屬性將包含字段的默認值,就像指定了默認值一樣。例如,之后: ``` @dataclass class C: x: int y: int = field(repr=False) z: int = field(repr=False, default=10) t: int = 20 ``` 類屬性 `C.z` 將是 `10` ,類屬性 `C.t` 將是 `20`,類屬性 `C.x` 和 `C.y` 將不設置。 *class* `dataclasses.``Field`[`Field`](#dataclasses.Field "dataclasses.Field") 對象描述每個定義的字段。這些對象在內部創建,并由 [`fields()`](#dataclasses.fields "dataclasses.fields") 模塊級方法返回(見下文)。用戶永遠不應該直接實例化 [`Field`](#dataclasses.Field "dataclasses.Field") 對象。 其有文檔的屬性是: > - `name` :字段的名字。 > - `type` :字段的類型。 > - `default` 、 `default_factory` 、 `init` 、 `repr` 、 `hash` 、 `compare` 以及 `metadata` 與具有和 [`field()`](#dataclasses.field "dataclasses.field") 聲明中相同的意義和值。 可能存在其他屬性,但它們是私有的,不能被審查或依賴。 `dataclasses.``fields`(*class\_or\_instance*)返回 [`Field`](#dataclasses.Field "dataclasses.Field") 對象的元組,用于定義此數據類的字段。 接受數據類或數據類的實例。如果沒有傳遞一個數據類或實例將引發 [`TypeError`](exceptions.xhtml#TypeError "TypeError") 。 不返回 `ClassVar` 或 `InitVar` 的偽字段。 `dataclasses.``asdict`(*instance*, *\**, *dict\_factory=dict*)將數據類 `instance` 轉換為字典(使用工廠函數 `dict_factory` )。每個數據類都轉換為其字段的字典,如 `name: value` 對。數據類、字典、列表和元組被遞歸。例如: ``` @dataclass class Point: x: int y: int @dataclass class C: mylist: List[Point] p = Point(10, 20) assert asdict(p) == {'x': 10, 'y': 20} c = C([Point(0, 0), Point(10, 4)]) assert asdict(c) == {'mylist': [{'x': 0, 'y': 0}, {'x': 10, 'y': 4}]} ``` 引發 [`TypeError`](exceptions.xhtml#TypeError "TypeError") 如果 `instance` 不是數據類實例。 `dataclasses.``astuple`(*instance*, *\**, *tuple\_factory=tuple*)將數據類 `instance` 轉換為元組(通過使用工廠函數 `tuple_factory` )。每個數據類都轉換為其字段值的元組。數據類、字典、列表和元組被遞歸。 繼續前一個例子: ``` assert astuple(p) == (10, 20) assert astuple(c) == ([(0, 0), (10, 4)],) ``` 引發 [`TypeError`](exceptions.xhtml#TypeError "TypeError") 如果 `instance` 不是數據類實例。 `dataclasses.``make_dataclass`(*cls\_name*, *fields*, *\**, *bases=()*, *namespace=None*, *init=True*, *repr=True*, *eq=True*, *order=False*, *unsafe\_hash=False*, *frozen=False*)創建一個名為 `cls_name` 的新數據類,字段為 `fields` 中定義的字段,基類為 `bases` 中給出的基類,并使用 `namespace` 中給出的命名空間進行初始化。 `fields` 是一個可迭代的元素,每個元素都是 `name` 、 `(name, type)` 或 `(name, type, Field)` 。 如果只提供``name`` , `type` 為 `typing.Any` 。 `init` 、 `repr` 、 `eq` 、 `order` 、 `unsafe_hash` 和 `frozen` 的值與它們在 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 中的含義相同。 此函數不是嚴格要求的,因為用于任何創建帶有 `__annotations__` 的新類的 Python 機制都可以應用 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 函數將該類轉換為數據類。提供此功能是為了方便。例如: ``` C = make_dataclass('C', [('x', int), 'y', ('z', int, field(default=5))], namespace={'add_one': lambda self: self.x + 1}) ``` 等價于 ``` @dataclass class C: x: int y: 'typing.Any' z: int = 5 def add_one(self): return self.x + 1 ``` `dataclasses.``replace`(*instance*, *\*\*changes*)創建一個 `instance` 相同類型的新對象,用 `changes` 中的值替換字段。如果 `instance` 不是數據類,則引發 [`TypeError`](exceptions.xhtml#TypeError "TypeError") 。如果 `changes` 中的值沒有指定字段,則引發 [`TypeError`](exceptions.xhtml#TypeError "TypeError") 。 新返回的對象通過調用數據類的 [`__init__()`](../reference/datamodel.xhtml#object.__init__ "object.__init__") 方法創建。這確保了如果存在 `__post_init__()` ,其也被調用。 如果存在沒有默認值的僅初始化變量,必須在調用 [`replace()`](#dataclasses.replace "dataclasses.replace") 時指定,以便它們可以傳遞給 [`__init__()`](../reference/datamodel.xhtml#object.__init__ "object.__init__") 和 `__post_init__()` 。 `changes` 包含任何定義為 `init=False` 的字段是錯誤的。在這種情況下會引發 [`ValueError`](exceptions.xhtml#ValueError "ValueError") 。 提前提醒 `init=False` 字段在調用 [`replace()`](#dataclasses.replace "dataclasses.replace") 時的工作方式。如果它們完全被初始化的話,它們不是從源對象復制的,而是在 `__post_init__()` 中初始化。估計 `init=False` 字段很少能被正確地使用。如果使用它們,那么使用備用類構造函數或者可能是處理實例復制的自定義 `replace()` (或類似命名的)方法可能是明智的。 `dataclasses.``is_dataclass`(*class\_or\_instance*)如果其參數是數據類或數據類實例,則返回 True ,否則返回 False 。 如果你需要知道一個類是否是一個數據類的實例(而不是一個數據類本身),那么再添加一個 `not isinstance(obj, type)` 檢查: ``` def is_dataclass_instance(obj): return is_dataclass(obj) and not isinstance(obj, type) ``` ## 初始化后處理 生成的 [`__init__()`](../reference/datamodel.xhtml#object.__init__ "object.__init__") 代碼將調用一個名為 `__post_init__()` 的方法,如果在類上已經定義了 `__post_init__()` 。它通常被稱為 `self.__post_init__()` 。但是,如果定義了任何 `InitVar` 字段,它們也將按照它們在類中定義的順序傳遞給 `__post_init__()` 。 如果沒有 `__ init__()` 方法生成,那么 `__post_init__()` 將不會被自動調用。 在其他用途中,這允許初始化依賴于一個或多個其他字段的字段值。例如: ``` @dataclass class C: a: float b: float c: float = field(init=False) def __post_init__(self): self.c = self.a + self.b ``` 有關將參數傳遞給 `__post_init__()` 的方法,請參閱下面有關僅初始化變量的段落。另請參閱關于 [`replace()`](#dataclasses.replace "dataclasses.replace") 處理 `init=False` 字段的警告。 ## 類變量 兩個地方 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 實際檢查字段類型的之一是確定字段是否是如 [**PEP 526**](https://www.python.org/dev/peps/pep-0526) \[https://www.python.org/dev/peps/pep-0526\] 所定義的類變量。它通過檢查字段的類型是否為 `typing.ClassVar` 來完成此操作。如果一個字段是一個 `ClassVar` ,它將被排除在考慮范圍之外,并被數據類機制忽略。這樣的 `ClassVar` 偽字段不會由模塊級的 [`fields()`](#dataclasses.fields "dataclasses.fields") 函數返回。 ## 僅初始化變量 另一個 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 檢查類型注解地方是為了確定一個字段是否是一個僅初始化變量。它通過查看字段的類型是否為 `dataclasses.InitVar` 類型來實現。如果一個字段是一個 `InitVar` ,它被認為是一個稱為僅初始化字段的偽字段。因為它不是一個真正的字段,所以它不會被模塊級的 [`fields()`](#dataclasses.fields "dataclasses.fields") 函數返回。僅初始化字段作為參數添加到生成的 [`__init__()`](../reference/datamodel.xhtml#object.__init__ "object.__init__") 方法中,并傳遞給可選的 `__post_init__()` 方法。數據類不會使用它們。 例如,假設一個字段將從數據庫初始化,如果在創建類時未提供其值: ``` @dataclass class C: i: int j: int = None database: InitVar[DatabaseType] = None def __post_init__(self, database): if self.j is None and database is not None: self.j = database.lookup('j') c = C(10, database=my_database) ``` 在這種情況下, [`fields()`](#dataclasses.fields "dataclasses.fields") 將返回 `i` 和 `j` 的 [`Field`](#dataclasses.Field "dataclasses.Field") 對象,但不包括 `database` 。 ## 凍結的實例 無法創建真正不可變的 Python 對象。但是,通過將 `frozen=True` 傳遞給 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 裝飾器,你可以模擬不變性。在這種情況下,數據類將向類添加 [`__setattr__()`](../reference/datamodel.xhtml#object.__setattr__ "object.__setattr__") 和 [`__delattr__()`](../reference/datamodel.xhtml#object.__delattr__ "object.__delattr__") 方法。 些方法在調用時會引發 [`FrozenInstanceError`](#dataclasses.FrozenInstanceError "dataclasses.FrozenInstanceError") 。 使用 `frozen=True` 時會有很小的性能損失: `__ init__()` 不能使用簡單的賦值來初始化字段,并必須使用 `object.__ setattr__()` 。 ## 繼承 當數組由 [`dataclass()`](#dataclasses.dataclass "dataclasses.dataclass") 裝飾器創建時,它會查看反向 MRO 中的所有類的基類(即從 [`object`](functions.xhtml#object "object") 開始 ),并且對于它找到的每個數據類, 將該基類中的字段添加到字段的有序映射中。添加完所有基類字段后,它會將自己的字段添加到有序映射中。所有生成的方法都將使用這種組合的,計算的有序字段映射。由于字段是按插入順序排列的,因此派生類會重載基類。一個例子: ``` @dataclass class Base: x: Any = 15.0 y: int = 0 @dataclass class C(Base): z: int = 10 x: int = 15 ``` 最后的字段列表依次是 `x` 、 `y` 、 `z` 。 `x` 的最終類型是 `int` ,如類 `C` 中所指定的那樣。 為 `C` 生成的 [`__init__()`](../reference/datamodel.xhtml#object.__init__ "object.__init__") 方法看起來像: ``` def __init__(self, x: int = 15, y: int = 0, z: int = 10): ``` ## 默認工廠函數 > 如果一個 [`field()`](#dataclasses.field "dataclasses.field") 指定了一個 `default_factory` ,當需要該字段的默認值時,將使用零參數調用它。例如,要創建列表的新實例,請使用: > > > ``` > mylist: list = field(default_factory=list) > > ``` > > > > > 如果一個字段被排除在 [`__init__()`](../reference/datamodel.xhtml#object.__init__ "object.__init__") 之外(使用 `init=False` )并且字段也指定 `default_factory` ,則默認的工廠函數將始終從生成的 `__ init__()` 函數調用。發生這種情況是因為沒有其他方法可以為字段提供初始值。 ## 可變的默認值 > Python 在類屬性中存儲默認成員變量值。思考這個例子,不使用數據類: > > > ``` > class C: > x = [] > def add(self, element): > self.x.append(element) > > o1 = C() > o2 = C() > o1.add(1) > o2.add(2) > assert o1.x == [1, 2] > assert o1.x is o2.x > > ``` > > > > > 請注意,類 `C` 的兩個實例共享相同的類變量 `x` ,如預期的那樣。 > > 使用數據類, *如果* 此代碼有效: > > > ``` > @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 > > assert D().x is D().x > > ``` > > > > > 這與使用類 `C` 的原始示例具有相同的問題。也就是說,在創建類實例時沒有為 `x` 指定值的類 `D` 的兩個實例將共享相同的 `x` 副本。由于數據類只使用普通的 Python 類創建,因此它們也會共享此行為。數據類沒有通用的方法來檢測這種情況。相反,如果數據類檢測到類型為 `list` 、 `dict` 或 `set` 的默認參數,則會引發 [`TypeError`](exceptions.xhtml#TypeError "TypeError") 。這是一個部分解決方案,但它可以防止許多常見錯誤。 > > 使用默認工廠函數是一種創建可變類型新實例的方法,并將其作為字段的默認值: > > > ``` > @dataclass > class D: > x: list = field(default_factory=list) > > assert D().x is not D().x > > ``` ## 異常 *exception* `dataclasses.``FrozenInstanceError`在使用 `frozen=True` 定義的數據類上調用隱式定義的 [`__setattr__()`](../reference/datamodel.xhtml#object.__setattr__ "object.__setattr__") 或 [`__delattr__()`](../reference/datamodel.xhtml#object.__delattr__ "object.__delattr__") 時引發。 ### 導航 - [索引](../genindex.xhtml "總目錄") - [模塊](../py-modindex.xhtml "Python 模塊索引") | - [下一頁](contextlib.xhtml "contextlib --- Utilities for with-statement contexts") | - [上一頁](warnings.xhtml "warnings --- Warning control") | - ![](https://box.kancloud.cn/a721fc7ec672275e257bbbfde49a4d4e_16x16.png) - [Python](https://www.python.org/) ? - zh\_CN 3.7.3 [文檔](../index.xhtml) ? - [Python 標準庫](index.xhtml) ? - [Python運行時服務](python.xhtml) ? - $('.inline-search').show(0); | ? [版權所有](../copyright.xhtml) 2001-2019, Python Software Foundation. Python 軟件基金會是一個非盈利組織。 [請捐助。](https://www.python.org/psf/donations/) 最后更新于 5月 21, 2019. [發現了問題](../bugs.xhtml)? 使用[Sphinx](http://sphinx.pocoo.org/)1.8.4 創建。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看