当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。