API 参考

attrs 通过使用 attrs.defineattr.s 装饰类,然后使用 attrs.fieldattr.ib 或类型注释在类上定义属性来工作。

以下是供理解 attrs 工作原理的人员阅读的干燥 API 说明。 如果您想要一个实践教程,请查看 attrs 示例

如果您对许多名称感到困惑,请查看 核心API中的名称(On The Core API Names) 以获得澄清,但 TL;DR 是,从版本 21.3.0 开始,attrs两个 顶级包名称组成:

  • 经典的 attr,为尊贵的 attr.sattr.ib 提供支持。

  • 更新的 attrs,仅包含大多数现代 API,并依赖 attrs.defineattrs.field 来定义您的类。 此外,一些在 attr 中也存在的 API 具有更好的默认值(例如,attrs.asdict)。

attrs 命名空间是 attr 之上构建的——attr永远 存在——并且同样稳定,因为它并不构成重写。 为了降低重复性并使文档保持在合理的大小, attr 命名空间在 在单独的页面上记录 上有单独的文档。

核心(Core)

attrs.define(maybe_cls=None, *, these=None, repr=None, unsafe_hash=None, hash=None, init=None, slots=True, frozen=False, weakref_slot=True, str=False, auto_attribs=None, kw_only=False, cache_hash=False, auto_exc=True, eq=None, order=False, auto_detect=True, getstate_setstate=None, on_setattr=None, field_transformer=None, match_args=True)

一个类装饰器, 它根据使用 类型注释field() 调用或 these 参数指定的 fields(字段) , 添加 双下划线方法

由于 attrs 会对现有类进行修补或替换, 因此您无法在 attrs 类中使用 object.__init_subclass__ , 因为它运行得太早。作为替代, 您可以在类上定义 __attrs_init_subclass__ 。此方法将在 attrs 类创建后调用该子类。另请参见 attrs 和 __init_subclass__

参数:
  • slots (bool) -- 创建一个更节省内存的 slotted class 。slotted 类通常优于默认的 dict 类, 但有一些您需要了解的注意事项, 因此我们建议您阅读 glossary entry

  • auto_detect (bool) --

    不必显式设置 initrepreqhash 参数, 假定它们被设置为 True 除非 其中一个参数的相关方法在 当前 类中实现(意味着它并不是从某个基类继承的)。

    例如, 通过自己在类上实现 __eq__ , attrs 将推断出 eq=False , 并且将不会创建 neither __eq__ nor __ne__ (但是 Python 类默认有一个合理的 __ne__, 因此在大多数情况下仅实现 __eq__ 应该足够)。

    将 True 或 False 传递给 initrepreqhash 将覆盖 auto_detect 的任何判断。

  • auto_exc (bool) --

    如果类继承自 BaseException (隐含包括任何异常的子类), 则会表现得像一个行为良好的 Python 异常类:

    • eqorderhash 的值将被忽略, 实例将根据实例的 ID 进行比较和哈希 [1],

    • 所有传递给 __init__ 或具有默认值的属性将额外作为元组在 args 属性中可用,

    • str 的值将被忽略, __str__ 将交给基类处理。

  • on_setattr (Callable | list[Callable] | None | Literal[attrs.setters.NO_OP]) --

    一个可调用对象, 在用户尝试设置属性(无论是通过赋值如 i.x = 42 还是使用 setattrsetattr(i, "x", 42))时运行。它接收与验证器相同的参数:实例、正在修改的属性和新值。

    如果没有引发异常, 该属性将被设置为可调用对象的返回值。

    如果传递了一个可调用对象的列表, 它们会自动包装在 attrs.setters.pipe 中。

    如果保持为 None, 默认行为是在设置属性时运行转换器和验证器。

  • init (bool) --

    创建一个 __init__ 方法, 用于初始化 attrs 属性。参数名的前导下划线会被去掉, 除非在属性上设置了别名。

    参见

    初始化(Initialization) 显示了自定义生成的 __init__ 方法的高级方法, 包括在前后执行代码。

  • repr (bool) -- 创建一个 __repr__ 方法, 用于生成 attrs 属性的可读表示。

  • str (bool) -- 创建一个与 __repr__ 相同的 __str__ 方法。除非是 Exception, 通常不需要这样做。

  • eq (bool | None) --

    如果为 True 或 None(默认), 则添加 __eq____ne__ 方法, 用于检查两个实例是否相等。

    参见

    比较(Comparison) 描述了如何自定义比较行为, 甚至可以比较 NumPy 数组。

  • order (bool | None) --

    如果为 True, 添加 __lt____le____gt____ge__ 方法, 这些方法的行为与上面的 eq 一样, 并允许实例进行排序。

    仅当两个类的类型完全相同时, 实例才会像它们的 attrs 属性元组一样进行比较。

    如果为 None, 则镜像 eq 的值。

  • unsafe_hash (bool | None) --

    如果为 None(默认), 则根据 eqfrozen 的设置生成 __hash__ 方法。

    1. 如果 两者 为 True, attrs 将为您生成一个 __hash__

    2. 如果 eq 为 True 且 frozen 为 False, __hash__ 将被设置为 None, 标记为不可哈希(确实如此)。

    3. 如果 eq 为 False, __hash__ 将保持不变, 意味着将使用基类的 __hash__ 方法。如果基类是 object, 这意味着将回退到基于 ID 的哈希。

    虽然不推荐, 您可以自行决定并强制 attrs 创建一个(例如, 如果类是不可变的, 即使您没有以编程方式冻结它)通过传递 True 或不传递。这两种情况都比较特殊, 应谨慎使用。

    参见

  • hash (bool | None) -- unsafe_hash 的弃用别名。unsafe_hash 优先。

  • cache_hash (bool) -- 确保对象的哈希码只计算一次并存储在对象上。如果设置为 True, 哈希必须显式或隐式启用。如果哈希码被缓存, 请避免在对象创建后对哈希码计算涉及的字段进行任何重新赋值或对这些字段指向的对象进行任何变更。如果发生这种变化, 对象的哈希码行为是未定义的。

  • frozen (bool) --

    使实例在初始化后不可变。如果有人试图修改一个冻结的实例, 将引发 attrs.exceptions.FrozenInstanceError

    备注

    1. 这是通过在您的类上安装一个自定义的 __setattr__ 方法实现的, 因此您无法实现自己的方法。

    2. 在 Python 中, 真正的不可变性是不可能的。

    3. 确实 对初始化新实例有轻微的运行时性能 影响。换句话说:使用 frozen=True 时, __init__ 会稍微慢一些。

    4. 如果一个类被冻结, 您不能在 __attrs_post_init__ 或自定义的 __init__ 中修改 self。您可以通过使用

      object.__setattr__(self, "attribute_name", value) 来规避该限制。

    5. 冻结类的子类也会被冻结。

  • kw_only (bool) -- 使生成的 __init__ 中所有属性仅限关键字参数(如果 init 为 False, 此参数将被忽略)。

  • weakref_slot (bool) -- 使实例可被弱引用。这在 slots 为 True 的情况下有效。

  • field_transformer (Callable | None) --

    一个函数, 在 attrs 最终确定类之前, 使用原始类对象和所有字段调用。您可以使用此功能, 例如, 自动根据字段的类型为字段添加转换器或验证器。

  • match_args (bool) -- 如果为 True(默认), 则在类上设置 __match_args__ 以支持 PEP 634 (结构模式匹配)。它是一个元组, 包含所有非关键字参数的 __init__ 参数名, 仅在 Python 3.10 及更高版本中可用。在较旧的 Python 版本中被忽略。

  • collect_by_mro (bool) --

    如果为 True, attrs 将根据 方法解析顺序 正确收集基类的属性。如果为 False, attrs 将模仿(错误的) dataclassesPEP 681 的行为。

    另请参见 issue #428

  • getstate_setstate (bool | None) --

    备注

    这通常仅对 slotted 类有趣, 您可能只需将 auto_detect 设置为 True。

    如果为 True, 将生成 __getstate____setstate__ 并附加到类上。这对于 slotted 类能够被 pickle 是必要的。如果为 None, 则 slotted 类默认为 True, 而 dict 类为 False。

    如果 auto_detect 为 True, 且 getstate_setstate 为 None, 且 任一 __getstate____setstate__ 直接在类上被检测到(意味着:不是继承的), 则它将被设置为 False(这通常是您想要的)。

  • auto_attribs (bool | None) --

    如果为 True, 查看类型注解以确定使用哪些属性, 类似于 dataclasses。如果为 False, 则仅查找显式的 field() 类属性, 类似于经典的 attrs

    如果为 None, 将进行推测:

    1. 如果有任何属性被注解且未找到未注解的 attrs.field, 则假设 auto_attribs=True

    2. 否则, 假设 auto_attribs=False 并尝试收集 attrs.field

    如果 attrs 决定查看类型注解, 所有 字段 必须 被注解。如果 attrs 遇到一个设置为 field() / attr.ib 但缺少类型注解的字段, 将引发 attrs.exceptions.UnannotatedAttributeError。如果您不想设置类型, 请使用 field_name: typing.Any = field(...)

    警告

    对于使用属性名称创建装饰器的功能(例如, validators), 您仍然 必须field() / attr.ib 分配给它们。否则, Python 将无法找到名称或尝试使用默认值调用, 例如 validator

    被标注为 typing.ClassVar 的属性, 以及既没有被注解又没有设置为 field() 的属性将被 忽略

  • these (dict[str, object]) --

    一个名称到 field() 返回值(私有)映射的字典。这对于避免在类体内定义您的属性很有用, 因为您不能(例如, 如果您想向 Django 模型添加 __repr__ 方法)或不想这样做。

    如果 these 不为 None, attrs 在类体中搜索属性, 并且将 从中删除任何属性。

    顺序由 these 中属性的顺序推导得出。

    可以说, 这是一个相当晦涩的功能。

Added in version 20.1.0.

在 21.3.0 版本发生变更: 转换器也在 on_setattr 上运行。

Added in version 22.2.0: unsafe_hash 作为 hash 的别名(为了兼容 PEP 681)。

在 24.1.0 版本发生变更: 实例不再作为属性元组进行比较, 而是使用一个大的 and 条件。这更快, 并且对于无法比较的值(如 math.nan)具有更正确的行为。

Added in version 24.1.0: 如果一个类有一个 继承的 类方法 __attrs_init_subclass__, 它将在类创建后执行。

自 24.1.0 版本弃用: hash 已被弃用, 取而代之的是 unsafe_hash

备注

与经典的 attr.s 的主要区别如下:

  • 自动检测 auto_attribs 是否应为 True

    (参见 auto_attribs 参数)。

  • 当属性被设置时, 转换器和验证器默认运行 --

    如果 frozenFalse

  • slots=True

    通常, 这只有好处, 并且在日常编程中几乎没有可见效果。但它 可能 导致一些意外行为, 因此请确保阅读 slotted classes

  • auto_exc=True

  • auto_detect=True

  • order=False

  • 一些仅在 Python 2 中相关或为向后兼容而保留的选项已被删除。

attrs.mutable(same_as_define)

attrs.define 相同。

Added in version 20.1.0.

attrs.frozen(same_as_define)

行为与 attrs.define 相同,但设置 frozen=Trueon_setattr=None

Added in version 20.1.0.

attrs.field(*, default=NOTHING, validator=None, repr=True, hash=None, init=True, metadata=None, type=None, converter=None, factory=None, kw_only=False, eq=None, order=None, on_setattr=None, alias=None)

创建一个新的 field / attribute 在类上。

警告

除非该类也使用 attrs.define (或类似的)进行装饰, 否则 无任何作用 !

参数:
  • default --

    如果使用 attrs 生成的 __init__ 方法且在实例化时未传递值, 或者使用 init=False 排除了该属性, 则使用此值。

    如果该值是 attrs.Factory 的实例, 则会使用其可调用对象构造新值(对于可变数据类型, 如列表或字典, 非常有用)。

    如果未设置默认值(或手动设置为 attrs.NOTHING ), 则在实例化时必须提供一个值;否则会引发 TypeError

  • factory (Callable) -- default=attr.Factory(factory) 的语法糖。

  • validator (Callable | list[Callable]) --

    可调用对象, 在 attrs 生成的 __init__ 方法调用后被调用。它们接收已初始化的实例、Attribute() 和传入的值。

    返回值不会被检查, 因此验证器必须自己抛出异常。

    如果传入一个 list , 其项将被视为验证器, 且必须全部通过。

    可以使用 attrs.validators.get_disabled / attrs.validators.set_disabled 全局禁用和重新启用验证器。

    验证器也可以使用装饰器语法设置, 如下所示。

  • repr (bool | Callable) -- 在生成的 __repr__ 方法中包含此属性。如果为 True, 则包含该属性;如果为 False, 则省略它。默认情况下, 使用内置的 repr() 函数。要覆盖属性值的格式, 可以传递一个可调用对象, 该对象接受一个值并返回一个字符串。请注意, 结果字符串将原样使用, 这意味着它将直接用于替代调用 ``repr()``(默认)。

  • eq (bool | Callable) --

    如果为 True(默认), 则在生成的 __eq____ne__ 方法中包含此属性, 以检查两个实例的相等性。要覆盖属性值的比较方式, 可以传递一个可调用对象, 该对象接受一个值并返回要比较的值。

  • order (bool | Callable) --

    如果为 True(默认), 则在生成的 __lt____le____gt____ge__ 方法中包含此属性。要覆盖属性值的排序方式, 可以传递一个可调用对象, 该对象接受一个值并返回要排序的值。

  • hash (bool | None) --

    在生成的 __hash__ 方法中包含此属性。如果为 None(默认), 则反映 eq 的值。这是根据 Python 规范的正确行为。将此值设置为其他任何值都*不推荐*。

  • init (bool) --

    在生成的 __init__ 方法中包含此属性。

    可以将其设置为 False, 并设置默认值。在这种情况下, 此属性将无条件地使用指定的默认值或工厂进行初始化。

  • converter (Callable | Converter) --

    一个可调用对象, 由 attrs 生成的 __init__ 方法调用, 以将属性值转换为所需的格式。

    如果传递的是普通的可调用对象, 它将作为唯一的位置参数传递传入的值。通过将可调用对象包装在 Converter 中, 可以接收额外的参数。

    无论哪种方式, 返回的值将用作属性的新值。在传递给验证器之前(如果有的话)将进行值的转换。

  • metadata (dict | None) --

    一个任意映射, 用于第三方代码。

  • type (type) --

    属性的类型。现在, 指定类型的首选方法是使用变量注释(见 PEP 526)。此参数是为了向后兼容和与 make_class 一起使用。无论使用何种方法, 类型将存储在 Attribute.type 中。

    请注意, attrs 本身并不会对该元数据执行任何操作。您可以将其作为自己代码的一部分或用于 静态类型检查

  • kw_only (bool) -- 在生成的 __init__ 中将此属性设置为仅通过关键字传递(如果 init 为 False, 则此参数被忽略)。

  • on_setattr (Callable | list[Callable] | None | Literal[attrs.setters.NO_OP]) -- 允许覆盖来自 attr.son_setattr 设置。如果留空为 None, 将使用来自 attr.son_setattr 值。设置为 attrs.setters.NO_OP 可对该属性**不**运行任何 setattr 钩子——无论 define() 中的设置如何。

  • alias (str | None) -- 在生成的 __init__ 方法中覆盖此属性的参数名称。如果留空为 None, 则默认为 name, 去掉前导下划线。请参见 私有属性和别名(Private Attributes and Aliases)

Added in version 20.1.0.

在 21.1.0 版本发生变更: eq, order, 和 cmp 同样接受自定义的 callable

Added in version 22.2.0: alias

Added in version 23.1.0: type 参数已重新添加;主要是为了 attrs.make_class 。请注意, 类型检查器会忽略这些元数据。

参见

attr.ib

class attrs.Attribute(name, default, validator, repr, cmp, hash, init, inherited, metadata=None, type=None, converter=None, kw_only=False, eq=None, eq_key=None, order=None, order_key=None, on_setattr=None, alias=None)

只读(Read-only) 属性表示。

警告

你永远不应该自己实例化这个类。

该类具有 attr.ib所有 参数(除了 factory ,它只是 default=Factory(...) 的语法糖),以及以下内容:

  • name (str): 属性的名称。

  • alias (str): 属性的 __init__ 参数名称,在任何显式覆盖和默认私有属性名称处理之后。

  • inherited (bool): 该属性是否从基类继承。

  • eq_keyorder_key (typing.CallableNone): 分别用于通过该属性比较和排序对象的可调用对象。这些是通过将可调用对象传递给 attr.ibeqordercmp 参数设置的。另请参见 comparison customization

这个类的实例经常用于反射目的,例如:

  • fields 返回它们的元组。

  • 验证器将它们作为第一个参数传递。

  • field transformer 钩子接收它们的列表。

  • alias 属性暴露字段的 __init__ 参数名称,应用了任何覆盖和默认的私有属性处理。

Added in version 20.1.0: inherited

Added in version 20.1.0: on_setattr

在 20.2.0 版本发生变更: inherited 不再考虑相等性检查和哈希。

Added in version 21.1.0: eq_keyorder_key

Added in version 22.2.0: alias

有关字段的完整版本历史,请参见 attr.ib

例如:

>>> import attrs
>>> from attrs import define, field

>>> @define
... class C:
...     x = field()
>>> attrs.fields(C).x
Attribute(name='x', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='x')
evolve(**changes)

拷贝 self 并应用 更改(changes).

这与 attrs.evolve 的工作方式类似,但该函数不适用于 {class}`Attribute` 。

主要用于 自动生成字段的转换和修改(Automatic Field Transformation and Modification)

Added in version 20.3.0.

attrs.make_class(name, attrs, bases=(<class 'object'>, ), class_body=None, **attributes_arguments)

一种快速创建名为 name 的新类并使用 attrs 的方法。

参数:
  • name (str) -- 新类的名称。

  • attrs (list | dict) --

    名称的列表或名称到 attr.ib / attrs.field 的映射字典。

    顺序从 attrs 内的名称或属性的顺序推断。否则,将使用属性定义的顺序。

  • bases (tuple[type, ...]) -- 新类将继承的类。

  • class_body (dict) -- 新类的可选类属性字典。

  • attributes_arguments -- 以未修改的方式传递给 attr.s

返回:

一个具有 attrs 的新类。

返回类型:

type

Added in version 17.1.0: bases

在 18.1.0 版本发生变更: If attrs is ordered, the order is retained.

在 23.2.0 版本发生变更: class_body

如果你想以编程方式创建类,这非常方便。

例如:

>>> C1 = attrs.make_class("C1", ["x", "y"])
>>> C1(1, 2)
C1(x=1, y=2)
>>> C2 = attrs.make_class("C2", {
...     "x": field(default=42),
...     "y": field(factory=list)
... })
>>> C2()
C2(x=42, y=[])
class attrs.Factory(factory, takes_self=False)

存储一个工厂可调用对象(factory callable)。

如果作为默认值传递给 attrs.field ,则该工厂用于生成新值。

参数:
  • factory (Callable) -- 一个可调用对象,根据 takes_self 的值,可以不接受参数或只接受一个必需的位置参数。

  • takes_self (bool) -- 将正在初始化的部分初始化实例作为位置参数传递。

Added in version 17.1.0: takes_self

例如:

>>> @define
... class C:
...     x = field(default=attrs.Factory(list))
...     y = field(default=attrs.Factory(
...         lambda self: set(self.x),
...         takes_self=True)
...     )
>>> C()
C(x=[], y=set())
>>> C([1, 2, 3])
C(x=[1, 2, 3], y={1, 2, 3})
attrs.NOTHING

用于指示缺少值的哨兵(Sentinel),当 None 含糊不清(ambiguous)时。

如果扩展 attrs,您可以使用 typing.Literal[NOTHING] 来表示一个值可能是 NOTHING

在 21.1.0 版本发生变更: bool(NOTHING) 现在返回 False。

在 22.2.0 版本发生变更: NOTHING 现在是一个 enum.Enum 变体。

Exceptions

所有异常都可以通过 attr.exceptionsattrs.exceptions 获得,它们是相同的。这意味着它们被引发和/或捕获的命名空间无关紧要:

>>> import attrs, attr
>>> try:
...     raise attrs.exceptions.FrozenError()
... except attr.exceptions.FrozenError:
...     print("this works!")
this works!
exception attrs.exceptions.PythonTooOldError

尝试使用一个需要更高 Python 版本的 attrs 特性。

Added in version 18.2.0.

exception attrs.exceptions.FrozenError

尝试修改一个被 冻结/不可变(frozen/immutable) 的实例或属性。

它的行为与 namedtuples 一致,使用相同的错误消息并继承自 AttributeError

Added in version 20.1.0.

exception attrs.exceptions.FrozenInstanceError

已尝试修改冻结(frozen)的实例。

Added in version 16.1.0.

exception attrs.exceptions.FrozenAttributeError

已尝试修改冻结(frozen)的属性。

Added in version 20.1.0.

exception attrs.exceptions.AttrsAttributeNotFoundError

attrs 函数找不到用户要求的属性。

Added in version 16.2.0.

exception attrs.exceptions.NotAnAttrsClassError

一个没有 attrs 的类已被传递到一个需要 attrs 的函数。

Added in version 16.2.0.

exception attrs.exceptions.DefaultAlreadySetError

定义字段时已设置默认值,并尝试使用装饰器重置。

Added in version 17.1.0.

exception attrs.exceptions.NotCallableError(msg, value)

需要可调用(callable)的字段(field)已被设置为不可调用的值。

Added in version 19.2.0.

exception attrs.exceptions.UnannotatedAttributeError

具有 auto_attribs=True 的类有一个没有类型注解的字段。

Added in version 17.3.0.

例如:

@attr.s(auto_attribs=True)
class C:
    x: int
    y = attr.ib()  # <- ERROR!

Helpers

attrs 提供了一些辅助方法,使得使用它更加容易:

attrs.cmp_using(eq=None, lt=None, le=None, gt=None, ge=None, require_same_type=True, class_name='Comparable')

创建一个可以传递给 attrs.fieldeq, ordercmp 参数以自定义字段比较的类。

如果提供了至少一个 {lt, le, gt, ge}eq ,生成的类将具有完整的排序方法。

参数:
  • eq (Callable | None) -- 用于评估两个对象相等性的可调用对象。

  • lt (Callable | None) -- 用于评估一个对象是否小于另一个对象的可调用对象。

  • le (Callable | None) -- 用于评估一个对象是否小于或等于另一个对象的可调用对象。

  • gt (Callable | None) -- 用于评估一个对象是否大于另一个对象的可调用对象。

  • ge (Callable | None) -- 用于评估一个对象是否大于或等于另一个对象的可调用对象。

  • require_same_type (bool) -- 当为 True 时,如果对象不是同一类型,则相等和排序方法将返回 NotImplemented

  • class_name (str | None) -- 类的名称。默认为 "Comparable"。

有关更多详细信息,请参阅 比较(Comparison)

Added in version 21.1.0.

attrs.fields(cls)

返回一个类的 attrs 属性的元组。

该元组还允许通过名称访问字段(fields)(请参见下面的示例)。

参数:

cls (type) -- 要进行反射的类。

抛出:
返回:

tuple (带名称访问器)的 attrs.Attribute

在 16.2.0 版本发生变更: 返回的元组允许通过名称访问字段。

在 23.1.0 版本发生变更: 增加对泛型类的支持。

例如:

>>> @define
... class C:
...     x = field()
...     y = field()
>>> attrs.fields(C)
(Attribute(name='x', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='x'), Attribute(name='y', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='y'))
>>> attrs.fields(C)[1]
Attribute(name='y', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='y')
>>> attrs.fields(C).y is attrs.fields(C)[1]
True
attrs.fields_dict(cls)

返回一个有序字典,包含类的 attrs 属性,字典的键为属性名称。

参数:

cls (type) -- 要进行反射的类。

抛出:
返回:

属性名称到定义的字典

返回类型:

dict[str, attrs.Attribute]

Added in version 18.1.0.

例如:

>>> @attr.s
... class C:
...     x = attr.ib()
...     y = attr.ib()
>>> attrs.fields_dict(C)
{'x': Attribute(name='x', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='x'), 'y': Attribute(name='y', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='y')}
>>> attr.fields_dict(C)['y']
Attribute(name='y', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None, alias='y')
>>> attrs.fields_dict(C)['y'] is attrs.fields(C).y
True
attrs.has(cls)

检查 cls 是否是具有 attrs 属性的类。

参数:

cls (type) -- 要检查的Class.

抛出:

TypeError -- 如果 cls 不是一个类(class).

返回类型:

bool

例如:

>>> @attr.s
... class C:
...     pass
>>> attr.has(C)
True
>>> attr.has(object)
False
attrs.resolve_types(cls, globalns=None, localns=None, attribs=None, include_extras=True)

解析类型注解中的任何字符串和前向注解(forward annotations)。

这仅在你需要在 Attributetype 字段中使用具体类型时才需要。换句话说,如果你只是用于静态类型检查,则无需解析你的类型。

如果没有参数,名称将会在创建类的模块中查找。如果这不是你想要的,例如,如果名称仅存在于方法内部,你可以传递 globalnslocalns 来指定其他字典以查找这些名称。有关更多详细信息,请参见 typing.get_type_hints 的文档。

参数:
  • cls (type) -- 要解析的类。

  • globalns (dict | None) -- 包含全局变量的字典。

  • localns (dict | None) -- 包含局部变量的字典。

  • attribs (list | None) -- 给定类的 attribs 列表。当从 field_transformer 内部调用时,这是必要的,因为 cls 还不是一个 attrs 类。

  • include_extras (bool) -- 如果可能,更准确地解析。如果类型模块支持,传递 include_extrastyping.get_hints 。在支持的 Python 版本(3.9+)上,这将更准确地解析类型。

抛出:
返回:

cls,这样你也可以将此函数用作类装饰器。请注意,必须在 attrs.define 之后 应用它。这意味着装饰器必须在 attrs.define 之前 出现。

Added in version 20.1.0.

Added in version 21.1.0: attribs

Added in version 23.1.0: include_extras

例如:

>>> import typing
>>> @define
... class A:
...     a: typing.List['A']
...     b: 'B'
...
>>> @define
... class B:
...     a: A
...
>>> attrs.fields(A).a.type
typing.List[ForwardRef('A')]
>>> attrs.fields(A).b.type
'B'
>>> attrs.resolve_types(A, globals(), locals())
<class 'A'>
>>> attrs.fields(A).a.type
typing.List[A]
>>> attrs.fields(A).b.type
<class 'B'>
attrs.asdict(inst, *, recurse=True, filter=None, value_serializer=None)

Same as attr.asdict, except that collections types are always retained and dict is always used as dict_factory.

attr.asdict 相同, 但集合类型始终被保留, 并且字典(dict)始终使用 dict_factory

Added in version 21.3.0.

例如:

>>> @define
... class C:
...     x: int
...     y: int
>>> attrs.asdict(C(1, C(2, 3)))
{'x': 1, 'y': {'x': 2, 'y': 3}}
attrs.astuple(inst, *, recurse=True, filter=None)

attr.asdict 相同, 但集合类型始终被保留, 并且元素(tuple)始终使用 tuple_factory

Added in version 21.3.0.

例如:

>>> @define
... class C:
...     x = field()
...     y = field()
>>> attrs.astuple(C(1,2))
(1, 2)

attrs 提供了用于过滤 attrs.asdictattrs.astuple 中属性的辅助工具:

attrs.filters.include(*what)

创建一个只允许 what 的过滤器。

参数:

what (list[type, str, attrs.Attribute]) -- 要包含的内容。可以是类型、名称或属性。

返回:

可传递给 attrs.asdictattrs.astuplefilter 参数的可调用对象。

返回类型:

Callable

在 23.1.0 版本发生变更: 接受字段名称的字符串。

attrs.filters.exclude(*what)

创建一个不允许 what 的过滤器。

参数:

what (list[type, str, attrs.Attribute]) -- 要排除的内容. 可以是一个类型(type), 名称(name), 或者属性(attribute).

返回:

A callable that can be passed to attrs.asdict's and attrs.astuple's filter argument.

可以传递给 attrs.asdictattrs.astuplefilter 参数的可调用函数。

返回类型:

Callable

在 23.3.0 版本发生变更: 接受字段名称字符串作为输入参数

attrs.asdict() 的示例.

来自 attrs.filters 的所有对象也可以从 attr.filters 访问(这是同一个模块在不同命名空间中的表现)。


attrs.evolve(*args, **changes)

创建一个新实例,基于第一个位置参数并应用 更改(changes)

参数:
  • inst -- 包含 attrs 属性的类的实例。inst 必须作为位置参数传递。

  • changes -- 新副本中的关键字更改。

返回:

一个包含 changes 的 inst 的副本。

抛出:

Added in version 17.1.0.

自 23.1.0 版本弃用: 现在不建议使用关键字参数 inst 来传递实例。直到 2024 年 4 月之前将引发警告,之后将变为错误。始终将实例作为位置参数传递。

在 24.1.0 版本发生变更: inst 不能再作为关键字参数传递。

例如:

>>> @define
... class C:
...     x: int
...     y: int
>>> i1 = C(1, 2)
>>> i1
C(x=1, y=2)
>>> i2 = attrs.evolve(i1, y=3)
>>> i2
C(x=1, y=3)
>>> i1 == i2
False

evolve 使用 __init__ 创建一个新实例。 这一事实有几个影响:

  • 私有属性应当不带前导下划线进行指定,和 __init__ 中一样。

  • 带有 init=False 的属性不能通过 evolve 进行设置。

  • 通常的 __init__ 验证器将验证新值。

attrs.validate(inst)

验证 inst 上所有具有验证器的属性。

所有异常都将抛出。

参数:

inst -- 包含 attrs 属性的类的实例。

例如:

>>> @define(on_setattr=attrs.setters.NO_OP)
... class C:
...     x = field(validator=attrs.validators.instance_of(int))
>>> i = C(1)
>>> i.x = "1"
>>> attrs.validate(i)
Traceback (most recent call last):
   ...
TypeError: ("'x' must be <class 'int'> (got '1' that is a <class 'str'>).", ...)

Validators

*attrs* 附带了一些常用的验证器,位于 attrs.validators 模块中。 所有来自 attrs.validators 的对象也可以通过 attr.validators 获得(这两个模块在不同的命名空间中是相同的)。

attrs.validators.lt(val)

一个验证器,如果初始化器使用大于或等于 val 的数字调用,则引发 ValueError

该验证器使用 operator.lt 来比较值。

参数:

val -- 值的排他上界。

Added in version 21.3.0.

例如:

>>> @define
... class C:
...     x = field(validator=attrs.validators.lt(42))
>>> C(41)
C(x=41)
>>> C(42)
Traceback (most recent call last):
   ...
ValueError: ("'x' must be < 42: 42")
attrs.validators.le(val)

一个验证器,如果初始化器使用大于 val 的数字调用,则引发 ValueError

该验证器使用 operator.le 来比较值。

参数:

val -- 值的包含上界。

Added in version 21.3.0.

例如:

>>> @define
... class C:
...     x = field(validator=attrs.validators.le(42))
>>> C(42)
C(x=42)
>>> C(43)
Traceback (most recent call last):
   ...
ValueError: ("'x' must be <= 42: 43")
attrs.validators.ge(val)

一个验证器,如果初始化器使用小于 val 的数字调用,则引发 ValueError

该验证器使用 operator.ge 来比较值。

参数:

val -- 值的包含下界。

Added in version 21.3.0.

例如:

>>> @define
... class C:
...     x = attrs.field(validator=attrs.validators.ge(42))
>>> C(42)
C(x=42)
>>> C(41)
Traceback (most recent call last):
   ...
ValueError: ("'x' must be => 42: 41")
attrs.validators.gt(val)

一个验证器,如果初始化器使用小于或等于 val 的数字调用,则引发 ValueError

该验证器使用 operator.ge 来比较值。

参数:

val -- 值的排他下界。

Added in version 21.3.0.

例如:

>>> @define
... class C:
...     x = field(validator=attrs.validators.gt(42))
>>> C(43)
C(x=43)
>>> C(42)
Traceback (most recent call last):
   ...
ValueError: ("'x' must be > 42: 42")
attrs.validators.max_len(length)

一个验证器,如果初始化器使用长度超过 length 的字符串或可迭代对象调用,则引发 ValueError

参数:

length (int) -- 字符串或可迭代对象的最大长度

Added in version 21.3.0.

例如:

>>> @define
... class C:
...     x = field(validator=attrs.validators.max_len(4))
>>> C("spam")
C(x='spam')
>>> C("bacon")
Traceback (most recent call last):
   ...
ValueError: ("Length of 'x' must be <= 4: 5")
attrs.validators.min_len(length)

一个验证器,如果初始化器使用长度短于 length 的字符串或可迭代对象调用,则引发 ValueError

参数:

length (int) -- 字符串或可迭代对象的最小长度

Added in version 22.1.0.

例如:

>>> @define
... class C:
...     x = field(validator=attrs.validators.min_len(1))
>>> C("bacon")
C(x='bacon')
>>> C("")
Traceback (most recent call last):
   ...
ValueError: ("Length of 'x' must be => 1: 0")
attrs.validators.instance_of(type)

一个验证器,如果初始化器使用错误类型调用该特定属性,则引发 TypeError (检查使用 isinstance 执行,因此也可以传递类型元组)。

参数:

type (type | tuple[type]) -- 要检查的类型。

抛出:

TypeError -- 带有人类可读的错误消息,属性(类型为 attrs.Attribute )、预期类型和它接收到的值。

例如:

>>> @define
... class C:
...     x = field(validator=attrs.validators.instance_of(int))
>>> C(42)
C(x=42)
>>> C("42")
Traceback (most recent call last):
   ...
TypeError: ("'x' must be <type 'int'> (got '42' that is a <type 'str'>).", Attribute(name='x', default=NOTHING, validator=<instance_of validator for type <type 'int'>>, type=None, kw_only=False), <type 'int'>, '42')
>>> C(None)
Traceback (most recent call last):
   ...
TypeError: ("'x' must be <type 'int'> (got None that is a <type 'NoneType'>).", Attribute(name='x', default=NOTHING, validator=<instance_of validator for type <type 'int'>>, repr=True, cmp=True, hash=None, init=True, type=None, kw_only=False), <type 'int'>, None)
attrs.validators.in_(options)

一个验证器,如果初始化器使用不在提供的 options 中的值调用,则引发 ValueError

检查使用 value in options 执行,因此 options 必须支持该操作。

为了保持验证器的可哈希性,字典、列表和集合会透明地转换为 tuple

参数:

options -- 允许的选项。

抛出:

ValueError -- 带有人类可读的错误消息,属性(类型为 attrs.Attribute)、预期选项和它接收到的值。

Added in version 17.1.0.

在 22.1.0 版本发生变更: 直到现在,ValueError 还不完整,仅包含人类可读的错误消息。现在它包含自 17.1.0 以来承诺的所有信息。

在 24.1.0 版本发生变更: 现在,作为列表、字典或集合的 options 被转换为元组,以保持验证器的可哈希性。

例如:

>>> import enum
>>> class State(enum.Enum):
...     ON = "on"
...     OFF = "off"
>>> @define
... class C:
...     state = field(validator=attrs.validators.in_(State))
...     val = field(validator=attrs.validators.in_([1, 2, 3]))
>>> C(State.ON, 1)
C(state=<State.ON: 'on'>, val=1)
>>> C("On", 1)
Traceback (most recent call last):
   ...
ValueError: 'state' must be in <enum 'State'> (got 'On'), Attribute(name='state', default=NOTHING, validator=<in_ validator with options <enum 'State'>>, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None), <enum 'State'>, 'on')
>>> C(State.ON, 4)
Traceback (most recent call last):
...
ValueError: 'val' must be in [1, 2, 3] (got 4), Attribute(name='val', default=NOTHING, validator=<in_ validator with options [1, 2, 3]>, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False, inherited=False, on_setattr=None), [1, 2, 3], 4)
attrs.validators.and_(*validators)

一个将多个验证器组合成一个的验证器。

当在一个值上调用时,它会运行所有封装的验证器。

参数:

validators (Iterable[Callable]) -- 任意数量的验证器。

Added in version 17.1.0.

为了方便,也可以将列表传递给 attrs.field 的验证器参数。

因此,以下两个语句是等效的:

x = field(validator=attrs.validators.and_(v1, v2, v3))
x = field(validator=[v1, v2, v3])
attrs.validators.or_(*validators)

一个将多个验证器组合成一个的验证器。

当在一个值上调用时,它会运行所有封装的验证器,直到满足其中一个。

参数:

validators (Iterable[Callable]) -- 任意数量的验证器。

抛出:

ValueError -- 如果没有验证器被满足。会抛出一个可读性强的错误消息,列出所有封装的验证器和未通过的值。

Added in version 24.1.0.

例如:

>>> @define
... class C:
...     val: int | list[int] = field(
...         validator=attrs.validators.or_(
...             attrs.validators.instance_of(int),
...             attrs.validators.deep_iterable(attrs.validators.instance_of(int)),
...         )
...     )
>>> C(42)
C(val=42)
>>> C([1, 2, 3])
C(val=[1, 2, 3])
>>> C(val='42')
Traceback (most recent call last):
   ...
ValueError: None of (<instance_of validator for type <class 'int'>>, <deep_iterable validator for iterables of <instance_of validator for type <class 'int'>>>) satisfied for value '42'
attrs.validators.not_(validator, *, msg=None, exc_types=(<class 'ValueError'>, <class 'TypeError'>))

一个包裹并逻辑上“反转”传入的验证器的验证器。 如果提供的验证器*没有*引发 ValueErrorTypeError (默认情况下), 将抛出 ValueError ,并且如果提供的验证器*确实*引发异常,则会抑制该异常。

旨在与现有验证器一起使用,以组合逻辑,而无需创建反转变体,例如,not_(in_(...))

参数:
  • validator -- 一个需要逻辑反转的验证器。

  • msg (str) -- 如果验证器失败时要抛出的消息。使用键 exc_typesvalidator 格式化。

  • exc_types (tuple[type, ...]) -- 要捕获的异常类型。子验证器引发的其他类型不会被拦截,将直接通过。

抛出:

ValueError -- 带有人类可读的错误消息,属性(类型为 attrs.Attribute ),未能引发异常的验证器, 以及获取的值和预期的异常类型。

Added in version 22.2.0.

例如:

>>> reserved_names = {"id", "time", "source"}
>>> @define
... class Measurement:
...     tags = field(
...         validator=attrs.validators.deep_mapping(
...             key_validator=attrs.validators.not_(
...                 attrs.validators.in_(reserved_names),
...                 msg="reserved tag key",
...             ),
...             value_validator=attrs.validators.instance_of((str, int)),
...         )
...     )
>>> Measurement(tags={"source": "universe"})
Traceback (most recent call last):
   ...
ValueError: ("reserved tag key", Attribute(name='tags', default=NOTHING, validator=<not_ validator wrapping <in_ validator with options {'id', 'time', 'source'}>, capturing (<class 'ValueError'>, <class 'TypeError'>)>, type=None, kw_only=False), <in_ validator with options {'id', 'time', 'source'}>, {'source_': 'universe'}, (<class 'ValueError'>, <class 'TypeError'>))
>>> Measurement(tags={"source_": "universe"})
Measurement(tags={'source_': 'universe'})
attrs.validators.optional(validator)

一个使属性可选的验证器。可选属性是指可以设置为 None ,并且满足 子验证器的要求。

参数:

validator -- (typing.Callable | tuple[typing.Callable] | list[typing.Callable]): 用于非 None 值的验证器(或验证器列表)。

Added in version 15.1.0.

在 17.1.0 版本发生变更: validator 可以是验证器列表。

在 23.1.0 版本发生变更: validator 也可以是验证器元组。

例如:

>>> @define
... class C:
...     x = field(
...         validator=attrs.validators.optional(
...             attrs.validators.instance_of(int)
...         ))
>>> C(42)
C(x=42)
>>> C("42")
Traceback (most recent call last):
   ...
TypeError: ("'x' must be <type 'int'> (got '42' that is a <type 'str'>).", Attribute(name='x', default=NOTHING, validator=<instance_of validator for type <type 'int'>>, type=None, kw_only=False), <type 'int'>, '42')
>>> C(None)
C(x=None)
attrs.validators.is_callable()

一个验证器,如果初始化器被调用时为此特定属性提供的值不可调用, 则会引发 attrs.exceptions.NotCallableError

Added in version 19.1.0.

抛出:

attrs.exceptions.NotCallableError -- 带有可读性错误信息,包含属性 (attrs.Attribute) 名称和获得的值。

例如:

>>> @define
... class C:
...     x = field(validator=attrs.validators.is_callable())
>>> C(isinstance)
C(x=<built-in function isinstance>)
>>> C("not a callable")
Traceback (most recent call last):
    ...
attr.exceptions.NotCallableError: 'x' must be callable (got 'not a callable' that is a <class 'str'>).
attrs.validators.matches_re(regex, flags=0, func=None)

一个验证器,如果初始化器被调用时提供的字符串不匹配 regex, 则会引发 ValueError

参数:

Added in version 19.2.0.

在 21.3.0 版本发生变更: regex 可以是预编译模式。

例如:

>>> @define
... class User:
...     email = field(validator=attrs.validators.matches_re(
...         r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"))
>>> User(email="user@example.com")
User(email='user@example.com')
>>> User(email="user@example.com@test.com")
Traceback (most recent call last):
    ...
ValueError: ("'email' must match regex '(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\\\.[a-zA-Z0-9-.]+$)' ('user@example.com@test.com' doesn't)", Attribute(name='email', default=NOTHING, validator=<matches_re validator for pattern re.compile('(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$)')>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), re.compile('(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$)'), 'user@example.com@test.com')
attrs.validators.deep_iterable(member_validator, iterable_validator=None)

一个验证器,执行对可迭代对象的深度验证。

参数:
  • member_validator -- 应用于可迭代成员的验证器。

  • iterable_validator -- 应用于可迭代对象本身的验证器(可选)。

Raises

TypeError: 如果任何子验证器失败

Added in version 19.1.0.

例如:

>>> @define
... class C:
...     x = field(validator=attrs.validators.deep_iterable(
...             member_validator=attrs.validators.instance_of(int),
...             iterable_validator=attrs.validators.instance_of(list)
...     ))
>>> C(x=[1, 2, 3])
C(x=[1, 2, 3])
>>> C(x=set([1, 2, 3]))
Traceback (most recent call last):
    ...
TypeError: ("'x' must be <class 'list'> (got {1, 2, 3} that is a <class 'set'>).", Attribute(name='x', default=NOTHING, validator=<deep_iterable validator for <instance_of validator for type <class 'list'>> iterables of <instance_of validator for type <class 'int'>>>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), <class 'list'>, {1, 2, 3})
>>> C(x=[1, 2, "3"])
Traceback (most recent call last):
    ...
TypeError: ("'x' must be <class 'int'> (got '3' that is a <class 'str'>).", Attribute(name='x', default=NOTHING, validator=<deep_iterable validator for <instance_of validator for type <class 'list'>> iterables of <instance_of validator for type <class 'int'>>>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), <class 'int'>, '3')
attrs.validators.deep_mapping(key_validator, value_validator, mapping_validator=None)

一个验证器,执行对字典的深度验证。

参数:
  • key_validator -- 应用于字典键的验证器。

  • value_validator -- 应用于字典值的验证器。

  • mapping_validator -- 应用于顶层映射属性的验证器(可选)。

Added in version 19.1.0.

抛出:

TypeError -- 如果任何子验证器失败

例如:

>>> @define
... class C:
...     x = field(validator=attrs.validators.deep_mapping(
...             key_validator=attrs.validators.instance_of(str),
...             value_validator=attrs.validators.instance_of(int),
...             mapping_validator=attrs.validators.instance_of(dict)
...     ))
>>> C(x={"a": 1, "b": 2})
C(x={'a': 1, 'b': 2})
>>> C(x=None)
Traceback (most recent call last):
    ...
TypeError: ("'x' must be <class 'dict'> (got None that is a <class 'NoneType'>).", Attribute(name='x', default=NOTHING, validator=<deep_mapping validator for objects mapping <instance_of validator for type <class 'str'>> to <instance_of validator for type <class 'int'>>>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), <class 'dict'>, None)
>>> C(x={"a": 1.0, "b": 2})
Traceback (most recent call last):
    ...
TypeError: ("'x' must be <class 'int'> (got 1.0 that is a <class 'float'>).", Attribute(name='x', default=NOTHING, validator=<deep_mapping validator for objects mapping <instance_of validator for type <class 'str'>> to <instance_of validator for type <class 'int'>>>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), <class 'int'>, 1.0)
>>> C(x={"a": 1, 7: 2})
Traceback (most recent call last):
    ...
TypeError: ("'x' must be <class 'str'> (got 7 that is a <class 'int'>).", Attribute(name='x', default=NOTHING, validator=<deep_mapping validator for objects mapping <instance_of validator for type <class 'str'>> to <instance_of validator for type <class 'int'>>>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), <class 'str'>, 7)

验证器可以在全局和局部两种情况下禁用:

attrs.validators.set_disabled(disabled)

全局禁用或启用运行验证器。

默认情况下,它们是运行的。

参数:

disabled (bool) -- 如果为 True,禁用运行所有验证器。

警告

此函数不是线程安全的!

Added in version 21.3.0.

attrs.validators.get_disabled()

返回一个布尔值,指示验证器当前是否被禁用。

返回:

如果验证器当前被禁用,则返回 True

返回类型:

bool

Added in version 21.3.0.

attrs.validators.disabled()

上下文管理器,在其上下文中禁用运行验证器。

警告

此上下文管理器不是线程安全的!

Added in version 21.3.0.

Converters

class attrs.Converter(converter, *, takes_self=False, takes_field=False)

存储一个转换器可调用对象。

允许包装的转换器接受额外的参数。参数按文档中的顺序传递。

参数:
  • converter (Callable) -- 用于转换传入值的可调用对象。

  • takes_self (bool) -- 将正在初始化的部分实例作为位置参数传递。 (默认值: False)

  • takes_field (bool) -- 将字段定义 (一个 Attribute) 作为位置参数传递给转换器。 (默认值: False)

Added in version 24.1.0.

例如:

>>> def complicated(value, self_, field):
...     return int(value) * self_.factor + field.metadata["offset"]
>>> @define
... class C:
...     factor = 5  # not an *attrs* field
...     x = field(
...         metadata={"offset": 200},
...         converter=attrs.Converter(
...             complicated,
...             takes_self=True, takes_field=True
...     ))
>>> C("42")
C(x=410)

attrs.converters 中的所有对象也可以从 attr.converters 访问(这两个命名空间中的模块是相同的)。

attrs.converters.pipe(*converters)

一个将多个转换器组合成一个的转换器。

当对一个值调用时,它会运行所有包装的转换器,并返回 最后 的值。

如果包装的转换器有类型注解,将会被推断出来。

converters (~collections.abc.Iterable[typing.Callable]):

任意数量的转换器。

Added in version 20.1.0.

为了方便,也可以将列表传递给 attrs.field / attr.ib 的转换器参数。

因此,以下两个语句是等效的:

x = attrs.field(converter=attrs.converter.pipe(c1, c2, c3))
x = attrs.field(converter=[c1, c2, c3])
attrs.converters.optional(converter)

一个允许属性可选的转换器。可选属性 可以设置为 None

如果包装的转换器有类型注解,将会被推断出来。

参数:

converter (Callable) -- 用于非 None 值的转换器。

Added in version 17.1.0.

例如:

>>> @define
... class C:
...     x = field(converter=attrs.converters.optional(int))
>>> C(None)
C(x=None)
>>> C(42)
C(x=42)
attrs.converters.default_if_none(default=NOTHING, factory=None)

一个允许将 None 值替换为 defaultfactory 结果的转换器。

参数:
  • default -- 如果传入 None,将使用的值。支持传入 attrs.Factory 的实例, 但是不支持 takes_self 选项。

  • factory (Callable) -- 一个不带参数的可调用,其结果将在传入 None 时使用。

抛出:

Added in version 18.2.0.

例如:

>>> @define
... class C:
...     x = field(
...         converter=attrs.converters.default_if_none("")
...     )
>>> C(None)
C(x='')
attrs.converters.to_bool(val)

将“布尔”字符串(例如,来自环境变量)转换为真实的布尔值。

映射为 True 的值:

  • True

  • "true" / "t"

  • "yes" / "y"

  • "on"

  • "1"

  • 1

映射为 False 的值:

  • False

  • "false" / "f"

  • "no" / "n"

  • "off"

  • "0"

  • 0

抛出:

ValueError -- 对于任何其他值。

Added in version 21.3.0.

例如:

>>> @define
... class C:
...     x = field(
...         converter=attrs.converters.to_bool
...     )
>>> C("yes")
C(x=True)
>>> C(0)
C(x=False)
>>> C("norway")
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
ValueError: Cannot convert value to bool: norway

Setters

这些是您可以与 attrs.defineattrs.fieldon_setattr 参数一起使用的助手。 attrs.setters 中的所有设置器也可以从 attr.setters 访问(它们是在不同命名空间中的相同模块)。

attrs.setters.frozen(_, __, ___)

防止属性被修改。

Added in version 20.1.0.

attrs.setters.validate(instance, attrib, new_value)

如果有的话, 在 new_value 上运行 attrib 的验证器。

Added in version 20.1.0.

attrs.setters.convert(instance, attrib, new_value)

如果有的话,在 new_value 上运行 attrib 的转换器并返回结果。

Added in version 20.1.0.

attrs.setters.pipe(*setters)

Run all setters and return the return value of the last one.

Added in version 20.1.0.

attrs.setters.NO_OP

用于禁用某些属性的类级 on_setattr 钩子的哨兵。

attrs.setters.pipe 或列表中无效。

Added in version 20.1.0.

例如,这里只有 x 是冻结(frozen)的:

>>> @define(on_setattr=attr.setters.frozen)
... class C:
...     x = field()
...     y = field(on_setattr=attr.setters.NO_OP)
>>> c = C(1, 2)
>>> c.y = 3
>>> c.y
3
>>> c.x = 4
Traceback (most recent call last):
    ...
attrs.exceptions.FrozenAttributeError: ()

小技巧

使用 attrs.definefrozen 参数(或 attrs.frozen)来冻结整个类;这样更有效。