如何在不注释类型的情况下添加数据类字段?

wim*_*wim 9 python annotations duck-typing python-3.7 python-dataclasses

当数据类中有一个类型可以是任何类型的字段时,如何省略注释?

@dataclass
class Favs:
    fav_number: int = 80085
    fav_duck = object()
    fav_word: str = 'potato'
Run Code Online (Sandbox Code Playgroud)

看来上面的代码实际上并没有创建一个字段fav_duck.它只是使它成为一个普通的旧类属性.

>>> Favs()
Favs(fav_number=80085, fav_word='potato')
>>> print(*Favs.__dataclass_fields__)
fav_number fav_word
>>> Favs.fav_duck
<object at 0x7fffea519850>
Run Code Online (Sandbox Code Playgroud)

ely*_*ely 8

根据定义数据类含义的PEP 557 ,

装饰dataclass器检查类以查找字段。字段定义为 中标识的任何变量__annotations__。也就是说,具有类型注释的变量。

也就是说,这个问题的前提(例如“我如何使用dataclass没有类型注释的字段”)必须被拒绝。术语“字段”在上下文中dataclass要求该属性根据定义具有类型注释。

请注意,使用像这样的泛型类型注释typing.Any与具有未注释的属性不同,因为该属性将出现在__annotations__.

最后,在仅提供属性名称的情况下,辅助函数make_dataclass将自动用于typing.Any类型注释,PEP 中也通过示例提到了这一点。


hab*_*ing 7

类型提示是 Python 的一个可选功能。这也意味着,使用@dataclass不需要您定义类型。

在注释中你可以写很多东西。如果您不想检查它们,则不会检查它们。这些示例有效:

@dataclass
class ColoredObject:
    color : "" 
    name : ""
Run Code Online (Sandbox Code Playgroud)
@dataclass
class ColoredObject:
    color : ... 
    name : ...
Run Code Online (Sandbox Code Playgroud)
@dataclass
class ColoredObject:
    color : True 
    name : True
Run Code Online (Sandbox Code Playgroud)
@dataclass
class ColoredObject:
    color : object
    name : object
Run Code Online (Sandbox Code Playgroud)
@dataclass
class ColoredObject:
    color : None
    name : None
Run Code Online (Sandbox Code Playgroud)

我在这里列出了很多选项,以便您可以决定是否喜欢其中一些。如何使用代码注释由您决定。

对于习惯了比 Python 更静态类型的语言的人来说,这可能是一种尴尬的风格。看起来像是滥用空字符串或 Ellipse 对象来达到此目的。这是真的。但请记住,代码的可读性在编程中也很重要。...有趣的是,如果您在编写代码时甚至不知道存在诸如 Ellipse 对象之类的东西,那么大多数代码读者都会直观地理解。

当然,如果您不想让喜欢类型提示的人感到困惑,或者如果您想使用期望正确类型提示的工具,则必须就此达成一致。

解决方案typing.Any我没有列出。当然这是一个很好的解决方案。但类型是 Python 的一个可选功能。这也意味着知道存在类似的东西typing.Any是可选知识。


wim*_*wim 6

数据类装饰器通过在中查找名称来检查类以查找字段__annotations__注解的存在使该字段成为现实,因此,您确实需要注解。

但是,您可以使用通用的一种:

@dataclass
class Favs:
    fav_number: int = 80085
    fav_duck: 'typing.Any' = object()
    fav_word: str = 'potato'
Run Code Online (Sandbox Code Playgroud)