从mypy中删除Python类中动态设置的属性的错误

Jea*_* T. 6 python mypy

mypy用来检查我的Python代码.

我有一个类,我动态设置一些属性,并mypy继续抱怨它:

error:"Toto" has no attribute "age"
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

class Toto:
    def __init__(self, name:str) -> None:
        self.name = name
        for attr in ['age', 'height']:
            setattr(self, attr, 0)


toto = Toto("Toto")
toto.age = 10  # "Toto" has no attribute "age" :(
Run Code Online (Sandbox Code Playgroud)

显然,可以有3种方法来解决这个问题

  1. 忽略问题# type: ignore:toto.age = 10 # type: ignore #...
  2. 使用setattr设定agetoto:setattr(toto, "age", 10)
  3. 明确设置属性(self.age = 0...)

但是,我在课堂上寻找更优雅,更系统的方式.

有什么建议吗?

jed*_*rds 5

我没有很好地遵循 mypy 以知道这是否(仍然或曾经是)理想的解决方法,但是这个问题和备忘单的这一部分表明类似:

from typing import Any

class Toto:
    def __init__(self, name:str) -> None:
        self.name = name
        for attr in ['age', 'height']:
            setattr(self, attr, 0)

    def __setattr__(self, name:str, value:Any):
        super().__setattr__(name, value)

toto = Toto("Toto")
toto.age = 10
Run Code Online (Sandbox Code Playgroud)

将允许你做你正在做的事情而没有 mypy 抱怨(它确实如此,刚刚测试过)。

Any可能更具限制性,但将在setattr()“传统”obj.attr = ...调用和“传统”调用中检查类型,因此请注意。

  • 这不是就违背了使用 mypy 的初衷吗?通过仅将所有属性的类型设置为“Any”,您将失去在其他地方进行类型检查的大量能力,或者将令人头疼的事情推到其他代码中 (2认同)