在其方法中使用 class 作为参数的类型提示
Using the class as a type hint for arguments in its methods
我在下面包含的代码抛出以下错误:
NameError: name 'Vector2' is not defined
在这一行:
def Translate (self, pos: Vector2):
为什么Python在Translate
方法中无法识别我的Vector2
class?
class Vector2:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def Translate(self, pos: Vector2):
self.x += pos.x
self.y += pos.y
因为遇到Translate
时(编译class体时),Vector2
还没有定义(正在编译,还没有进行名称绑定); Python自然是抱怨。
因为这是一个很常见的场景(在 class 的正文中类型提示 class),你应该使用 forward reference 用引号引起来:
class Vector2:
# __init__ as defined
def Translate(self, pos: 'Vector2'):
self.x += pos.x
self.y += pos.y
Python(以及任何遵守 PEP 484
的检查器)将理解您的提示并适当地注册它。当通过 typing.get_type_hints
:
访问 __annotations__
时,Python 确实识别了这一点
from typing import get_type_hints
get_type_hints(Vector2(1,2).Translate)
{'pos': __main__.Vector2}
自 Python 3.7 起已更改;参见 。
您要求的功能称为前向(类型)引用,它已添加到 Python 3.7(在 PEP 563 中)。1 所以这现在有效了:
from __future__ import annotations
class C:
def spam(self, other: C) -> C:
pass
注意 __future__
statement. This will be necessary until 4.0.
不幸的是,在 Python 3.6 及更早版本中,此功能不可用,因此您必须使用字符串注释,如 中所述。
Mypy 已经支持前向声明,即使 运行 在 Python 3.6 下也是如此——但如果静态类型检查器说你的代码没问题但解释器提出NameError
当你尝试实际 运行 时。
1.这已经在 PEP 484 中作为一个可能的功能进行了讨论,但推迟到后来,在人们对在注释中使用前向声明有更多经验之后。 PEP 563/Python 3.7 是 "later".
也许另一种选择是预先定义 class,使用空实现。我想最常见的解决方案是 forward reference 但我的建议是类型安全的,毕竟这是添加类型的目的。
class Vector2:
pass
class Vector2:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def Translate(self, pos: Vector2):
self.x += pos.x
self.y += pos.y
我在下面包含的代码抛出以下错误:
NameError: name 'Vector2' is not defined
在这一行:
def Translate (self, pos: Vector2):
为什么Python在Translate
方法中无法识别我的Vector2
class?
class Vector2:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def Translate(self, pos: Vector2):
self.x += pos.x
self.y += pos.y
因为遇到Translate
时(编译class体时),Vector2
还没有定义(正在编译,还没有进行名称绑定); Python自然是抱怨。
因为这是一个很常见的场景(在 class 的正文中类型提示 class),你应该使用 forward reference 用引号引起来:
class Vector2:
# __init__ as defined
def Translate(self, pos: 'Vector2'):
self.x += pos.x
self.y += pos.y
Python(以及任何遵守 PEP 484
的检查器)将理解您的提示并适当地注册它。当通过 typing.get_type_hints
:
__annotations__
时,Python 确实识别了这一点
from typing import get_type_hints
get_type_hints(Vector2(1,2).Translate)
{'pos': __main__.Vector2}
自 Python 3.7 起已更改;参见
您要求的功能称为前向(类型)引用,它已添加到 Python 3.7(在 PEP 563 中)。1 所以这现在有效了:
from __future__ import annotations
class C:
def spam(self, other: C) -> C:
pass
注意 __future__
statement. This will be necessary until 4.0.
不幸的是,在 Python 3.6 及更早版本中,此功能不可用,因此您必须使用字符串注释,如
Mypy 已经支持前向声明,即使 运行 在 Python 3.6 下也是如此——但如果静态类型检查器说你的代码没问题但解释器提出NameError
当你尝试实际 运行 时。
1.这已经在 PEP 484 中作为一个可能的功能进行了讨论,但推迟到后来,在人们对在注释中使用前向声明有更多经验之后。 PEP 563/Python 3.7 是 "later".
也许另一种选择是预先定义 class,使用空实现。我想最常见的解决方案是 forward reference 但我的建议是类型安全的,毕竟这是添加类型的目的。
class Vector2:
pass
class Vector2:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def Translate(self, pos: Vector2):
self.x += pos.x
self.y += pos.y