如何指定一个属性必须是整数列表,而不仅仅是列表?

9

使用attrs库和Python 3.6,我认为以下内容可以让我指定xy只能包含整数:

import attr

@attr.s
class C:
  x : List[int] = attr.ib()   # not working
  y = attr.ib(type=List[int]) # not working either

两条被注释掉的代码都会抛出一个 NameError: name 'List' is not defined 的错误。

我期望它们能工作的原因如下:

(1) attr文档中的types部分包括以下内容:“attrs还允许您使用attr.ib()的type参数或使用Python 3.6的PEP 526-annotations将类型与属性关联”。然后演示了这两种方法:

@attr.s
class C:
    x = attr.ib(type=int)
    y: int = attr.ib()

(2)PEP 526规定了以下类型注解的语法是有效的:primes: List[int] = []

1个回答

9
这个语法确实是有效的。但是PEP 484添加的通用类型注释对象不在内置命名空间中,而是在typing模块中。
因此,你需要按照你提供的attrs文档、PEP 484、PEP 483、PEP 526和typing文档中的所有示例来操作:
from typing import List

此外,请注意这只是一个注释。您仍然可以编写c = C(x = [],y = [1.0]),并且不会收到 TypeError 。正如您链接的文档所说:

attrs本身没有任何在类型元数据之上工作的功能。但是,它对编写自己的验证器或序列化框架很有用。

并不清楚 attrs 应该如何处理这些元数据。 PEP 483 / PEP 484 的设计的核心部分是类型注释仅仅是运行时的注释,并不影响值的类型或存储位置的合法性。它们只是供静态类型检查器和其他与Python分开运行的工具使用。
特别地,Mypy(参考标准的静态类型检查器),一些代码检查工具和一些集成开发环境应该将此标记为错误。如果它们尚未支持attrib注释,则几乎可以肯定它们正在努力(因为它们与3.7/PEP 557 dataclass中的注释属性大致相当)。

谢谢!现在它能编译了,但仍然让我使用字符串列表。 - Jeffrey Benjamin Brown
@JeffreyBenjaminBrown 是的,因为静态类型注释不会影响动态类型。这是 PEP 483/PEP 484 设计的核心,也在你链接的文档中以一个大粉色框标出。我会编辑答案并进行更详细的解释。 - abarnert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接