Python 将类用作其方法中参数的类型提示
我在下面包含的代码引发以下错误:Python 将类用作其方法中参数的类型提示,python,python-3.x,oop,type-hinting,Python,Python 3.x,Oop,Type Hinting,我在下面包含的代码引发以下错误: NameError: name 'Vector2' is not defined 在这一行: def Translate (self, pos: Vector2): 为什么Python不能在Translate方法中识别我的Vector2类 class Vector2: def __init__(self, x: float, y: float): self.x = x self.y = y def Tr
NameError: name 'Vector2' is not defined
在这一行:
def Translate (self, pos: Vector2):
为什么Python不能在Translate
方法中识别我的Vector2
类
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
(在编译类主体时),Vector2
尚未定义(它当前正在编译,尚未执行名称绑定);Python自然会抱怨
由于这是一种常见的场景(类型在该类的主体中暗示一个类),因此您应该通过将其括在引号中来使用:
class Vector2:
# __init__ as defined
def Translate(self, pos: 'Vector2'):
self.x += pos.x
self.y += pos.y
Python(以及任何符合PEP 484的检查程序)将理解您的提示并适当注册。当通过以下方式访问\uuu注释时,Python会识别出这一点:
从Python3.7开始,这一点已经改变;请参阅。您所要求的功能称为转发(类型)引用,并且从3.7(in.1)起已将其添加到Python中,因此这现在是有效的:
from __future__ import annotations
class C:
def spam(self, other: C) -> C:
pass
请注意。这是必要的
不幸的是,在Python 3.6及更早版本中,此功能不可用,因此必须使用字符串注释,如中所述
Mypy已经支持转发声明,即使在Python3.6下运行,但是如果静态类型检查器说您的代码很好,但是当您尝试实际运行它时,解释器会引发一个NameError
,这对您没有多大好处
一,。这已经在中作为一个可能的特性进行了讨论,但推迟到后来,因为人们在注释中有了更多使用前向声明的经验。PEP 563/Python3.7是“以后”的版本。也许另一种选择是以前定义类,使用空实现。我想最常见的解决方案是,但我的建议是更安全的类型,这毕竟是添加类型的目的
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
你能给我提供一个好的信息源,让我更多地了解Python是如何在我的源代码中运行的吗?我感兴趣的是,当Python还没有定义我的类时,当它正在处理同一个类的实例方法时,会发生什么。@Vanitas Hm,您可以看看类定义。他通常写了一系列很好的文章来描述Python是如何工作的。快速阅读了这篇文章和Eli Bendersky的其他一些文章,还发现了你关于Python 3.5中类型暗示的文章。我会好好阅读这些文章,谢谢分享。:)
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