![](/img/trans.png)
[英]How to declare python dataclass member field same as the dataclass type
[英]How to add a dataclass field without annotating the type?
當數據類中有一個類型可以是任何類型的字段時,如何省略注釋?
@dataclass
class Favs:
fav_number: int = 80085
fav_duck = object()
fav_word: str = 'potato'
看起來上面的代碼實際上並沒有為fav_duck
創建一個字段。 它只是使它成為一個普通的舊 class 屬性。
>>> Favs()
Favs(fav_number=80085, fav_word='potato')
>>> print(*Favs.__dataclass_fields__)
fav_number fav_word
>>> Favs.fav_duck
<object at 0x7fffea519850>
數據類裝飾器通過查找__annotations__
名稱來檢查類以查找字段。 它是存在的注釋,使得該字段 ,因此,您需要一個注釋。
但是,您可以使用通用的:
@dataclass
class Favs:
fav_number: int = 80085
fav_duck: 'typing.Any' = object()
fav_word: str = 'potato'
類型提示是 Python 的可選功能。這也意味着,使用@dataclass
不需要您定義類型。
在注釋中你可以寫很多東西。 如果您不想檢查它們,則不會檢查它們。 這些示例有效:
@dataclass
class ColoredObject:
color : ""
name : ""
@dataclass
class ColoredObject:
color : ...
name : ...
@dataclass
class ColoredObject:
color : True
name : True
@dataclass
class ColoredObject:
color : object
name : object
@dataclass
class ColoredObject:
color : None
name : None
我在這里列出了很多選項,以便您可以決定是否喜歡其中的一些選項。 如何使用代碼注釋由您決定。
對於比 Python 更習慣靜態類型語言的人來說,這可能是一種尷尬的風格。 為此,它看起來像是在濫用空字符串或橢圓 object。 這是真的。 但請記住,代碼可讀性在編程中也很重要。 有趣的是,如果您編寫...
,您的代碼的大多數讀者會憑直覺理解,甚至不知道存在類似橢圓 object 的東西。
當然,如果您不想讓喜歡類型提示的人感到困惑,或者如果您想要使用期望正確類型提示的工具,則必須就此達成協議。
typing.Any
的解決方案我沒有列出。 當然這是一個很好的解決方案。 但是類型是 Python 的一個可選特性。這也意味着知道有類似typing.Any
的東西是可選的知識。
如果您能夠在文件頂部添加from __future__ import annotations
,這會將文件中的所有注釋轉換為字符串,以便隨后對它們進行延遲評估; 這對於定義不需要在運行時解析的注釋非常有用。
例如,一種為字段使用簡短類型注釋 ( _
) 的方法:
from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING
# added to silence any IDE warnings (i.e. PyCharm)
if TYPE_CHECKING:
_ = object
@dataclass
class Favs:
fav_number: int = 80085
fav_duck: _ = object()
fav_word: str = 'potato'
print(Favs())
印刷:
Favs(fav_number=80085, fav_duck=<object object at 0x11b754ad0>, fav_word='potato')
如果您不想或不能使用__future__
導入(即,如果您使用的是 Python 3.6 或更低版本,或者想要消除 IDE 的“未解析引用”警告),您始終可以預先為類型注釋定義一個值:
from dataclasses import dataclass
# or:
# = ...
_ = object
@dataclass
class Favs:
fav_number: int = 80085
fav_duck: _ = object()
fav_word: str = 'potato'
print(Favs())
根據PEP 557定義數據類的含義,
dataclass
裝飾器檢查類以查找字段。 字段定義為__annotations__
標識的任何變量。 也就是說,具有類型注釋的變量。
這是說,這個問題的前提下(如“我如何使用dataclass
與沒有類型注釋字段)必須被拒絕。在上下文中的術語‘場’ dataclass
的必要條件是屬性有一個類型的注釋通過定義。
請注意,使用類似於typing.Any
的泛型類型注釋。任何與具有未注釋屬性的注釋不同,因為該屬性將出現在__annotations__
。
最后,輔助函數make_dataclass
將自動使用typing.Any
用於在僅提供屬性名稱的情況下的類型注釋,並且在PEP中也提到了一個示例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.