python - 实例变量 Python 的类型提示约定

标签 python python-3.x type-hinting instance-variables python-typing

我不确定类型提示实例变量的 Python 约定 - 我一直在 __init__ 构造函数参数中处理它们 like seen here :

class LoggedVar(Generic[T]):
    def __init__(self, value: T, name: str, logger: Logger) -> None:
        self.name = name
        self.logger = logger
        self.value = value`

但我也看到了 PEP 约定这样注释实例变量(下面的片段),然后还在 __init__ 参数中进行类型提示:

class BasicStarship:
    captain: str = 'Picard'               # instance variable with default
    damage: int                           # instance variable without default
    stats: ClassVar[Dict[str, int]] = {}  # class variable`

    def __init__(self, damage: int, captain: str = None):
        self.damage = damage
        if captain:
            self.captain = captain  # Else keep the default

最后,在 PEP 526 文章的后面,他们说为了方便和约定,可以执行以下操作:

class Box(Generic[T]):
    def __init__(self, content):
        self.content: T = content

(以上两段代码均来自here。)

那么 — 这些约定中的一个是否比我应该尝试坚持的其他约定更好/更广泛接受(更好的可读性等)?

最佳答案

我建议使用第一个版本,在大多数情况下,您可以将类型分配给 __init__ 方法的参数。

该特定方法具有最少的冗余,同时仍允许类型检查器验证您是否在代码中的其他地方正确调用了该 __init__ 方法。

我建议使用第二个或第三个版本,当您的 __init__ 方法变得足够复杂到以下一项或多项适用的点:

  1. 您的字段究竟以什么开头不再那么简单
  2. 参数和字段之间不再是一对一的映射
  3. 您有复杂的初始化逻辑,使您的字段分配方式变得模糊不清。

但是,我不清楚第二个还是第三个版本更受欢迎——我个人更喜欢第三个版本,因为它在概念上更清晰,而且似乎没有混淆实例属性和类属性的概念,但我可以不可否认第二个版本看起来更干净。

我在“打字”gitter channel 上询问了这个问题,并从 Guido 那里得到了以下回复(如果你不知道,他制作了 Python,目前正在研究 mypy 和打字相关的东西):

There seem to be strong opinions either way. I do indeed prefer putting attribute annotations in the class body rather than sprinkling them throughout __init__ and other methods. I also think that with PEP 526 this will be the future (also with things like class-based NamedTuple declarations and possibly https://github.com/ericvsmith/dataclasses).

( link to quote )

因此,似乎第二个版本优于第三个版本,并且在未来的某个时候,以这种方式定义的类将更深入地集成到 Python 语言本身中!

编辑: PEP 557, data classesrecently accepted并且似乎在轨道上(?)包含在 Python 3.7 中。

关于python - 实例变量 Python 的类型提示约定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44959876/

相关文章:

Python 以一种棘手的方式连接列表元素

python - 为什么 Visual Studio Code 不断更改工作目录?

python - 在列表中查找第一个元素和索引匹配条件

python - Django url参数传递

python - 冲突 'order' 模型在应用程序 'order'

python-3.x - Python数据保存性能

python - 删除 tkinter 中的特定小部件

python - 如何在声明类之前为类中使用的类型添加别名?

python - 使用可变泛型进行方法返回专门化

python - 如何对字典进行子类化,使其支持通用类型提示?