Python 如何注释现有对象的变量?(与mypy合作)
显然,PEP526允许我尝试使用最基本的语法Python 如何注释现有对象的变量?(与mypy合作),python,python-3.x,mypy,python-typing,python-importlib,Python,Python 3.x,Mypy,Python Typing,Python Importlib,显然,PEP526允许我尝试使用最基本的语法 obj.attr:注释 然而,就我所知,类型检查器显然不必支持这种语法。mypy给出了错误类型不能在赋值给非self属性中声明 现在,根据我在typeshed上的github上发现的另一个问题,您可以进行断言,让mypy知道对象所属的类型。而不是打字 assert-isinstance(obj.attr,注解) 然而,对我来说,这感觉是错误的。如果可能的话,我正在尝试使用键入功能,我正在尝试贡献的项目使用mypy作为它们的类型检查器 有效但让我讨厌自
obj.attr:注释
然而,就我所知,类型检查器显然不必支持这种语法。mypy给出了错误类型不能在赋值给非self属性中声明
现在,根据我在typeshed上的github上发现的另一个问题,您可以进行断言,让mypy知道对象所属的类型。而不是打字
assert-isinstance(obj.attr,注解)
然而,对我来说,这感觉是错误的。如果可能的话,我正在尝试使用键入功能,我正在尝试贡献的项目使用mypy作为它们的类型检查器
有效但让我讨厌自己的断言版本是:
def get_source(import_name: str) -> Optional[str]:
spec = get_spec(import_name)
# Now, here. The spec.loader might be one of several values.
# But I *know* that it is gonna be importlib.machinery.SourceFileloader
# I need to typecast the attribute of the spec.loader into the above
if spec and spec.loader.path.endswith('.py'):
return spec.loader.get_data(spec.loader.path).decode("utf-8")
return None
def get_spec(import_name: str) -> importlib.machinery.ModuleSpec:
try:
return importlib.util.find_spec(import_name)
except (ImportError, AttributeError, TypeError, ValueError):
return None
我读过的无数打字和mypy问题都没有帮助,所以我在这里。断言在我看来是语义上合适的选项。类型注释是不合适的-静态地说,您实际上不知道spec
是SourceFileLoader
。你在做一个动态断言。从技术上讲,有键入.cast
,但这不太安全typing.cast
对于无法动态检查或动态检查代价高昂的静态类型更有意义。我尝试了typing.cast
,但无法完全弄清楚它是如何工作的,比如说,spec.loader
肯定是SourceFileLoader
,这就是为什么我们不检查是否已经是FileLoader
或SourceLoader
。我应该如何让mypy知道这一点?使用断言
。我认为问题在于,当注释真正涉及定义时,您将其视为一种声明。您希望使用注释向类型检查器声明此特定代码位置中的spec.loader
的此特定值是SourceFileLoader,但mypy将其视为一个没有意义的定义。spec.loader
的类型已经在别处定义过了,在这里重新定义它是没有意义的。类型注释是不合适的-静态地说,您实际上不知道spec
是SourceFileLoader
。你在做一个动态断言。从技术上讲,有键入.cast
,但这不太安全typing.cast
对于无法动态检查或动态检查代价高昂的静态类型更有意义。我尝试了typing.cast
,但无法完全弄清楚它是如何工作的,比如说,spec.loader
肯定是SourceFileLoader
,这就是为什么我们不检查是否已经是FileLoader
或SourceLoader
。我应该如何让mypy知道这一点?使用断言
。我认为问题在于,当注释真正涉及定义时,您将其视为一种声明。您希望使用注释向类型检查器声明此特定代码位置中的spec.loader
的此特定值是SourceFileLoader,但mypy将其视为一个没有意义的定义。spec.loader
的类型已经在别处定义过,在这里重新定义它没有意义。
def get_source(import_name: str) -> Optional[str]:
spec = get_spec(import_name)
assert isinstance(spec.loader, importlib.machinery.SourceFileLoader)
assert isinstance(spec.loader.path, str)
if spec and spec.loader.path.endswith('.py'):
return spec.loader.get_data(spec.loader.path).decode("utf-8")
return None