如何指定属性必须是(比如说)整数列表,而不仅仅是列表?

Posted

技术标签:

【中文标题】如何指定属性必须是(比如说)整数列表,而不仅仅是列表?【英文标题】:How to specify that an attribute must be a list of (say) integers, not just a list? 【发布时间】:2018-09-03 11:40:31 【问题描述】:

使用attrs libary 和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) types section of the attr documentation 包括以下段落:“attrs 还允许您使用 attr.ib() 的类型参数或(从 Python 3.6 开始)使用 PEP 526 将类型与属性相关联-注释”。然后演示这两种方法:

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

(2) PEP 526 声明以下类型注释的语法是有效的:primes: List[int] = []

【问题讨论】:

【参考方案1】:

语法确实有效。但是PEP 484添加的泛型类型注解对象不在builtins命名空间中,而是在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(参考标准静态类型检查器)、一些 linter 和一些 IDE 应该将此标记为错误。如果他们还不支持attrib 注释,他们几乎肯定会在处理它(因为它们大致相当于3.7/PEP 557 dataclass 中的注释属性)。

【讨论】:

谢谢!现在它编译了,但它仍然让我使用字符串列表。 @JeffreyBenjaminBrown 是的,因为静态类型注释不会影响动态类型。这是 PEP 483/PEP 484 设计的核心,并且在你链接的文档中特别提到了一个粉红色的大框。我将编辑答案以解释更多。

以上是关于如何指定属性必须是(比如说)整数列表,而不仅仅是列表?的主要内容,如果未能解决你的问题,请参考以下文章

ls命令实战

什么是列级约束

TypeError:列表索引必须是整数或切片,而不是列表

Python'列表索引必须是整数,而不是元组”错误

“列表索引必须是整数,而不是 str”

TypeError:列表索引必须是整数,而不是浮点数