Python - 在同一个类中的函数参数类类型 In Python, it is possible to define a class type for function parameters within the same class. This can be useful when you want to define a specific type for the input arguments of a class method. To define a class type for a fu
Python - 在同一个类中的函数参数类类型 In Python, it is possible to define a class type for function parameters within the same class. This can be useful when you want to define a specific type for the input arguments of a class method. To define a class type for a fu
我下面附上的代码会产生以下错误:\n
NameError: name 'Vector2' is not defined
\n在这行代码上:\n
def Translate (self, pos: Vector2):
\n为什么Python在Translate
方法中无法识别我的Vector2
类?\n
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
问题的出现原因是在同一个类中,函数参数的类类型在函数定义之前定义。这导致在使用intellisense时无法提供正确的建议。
解决方法是先定义一个空的类实现,然后再定义具有参数类型的函数。这种方法比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
然而,在使用Visual Studio Code时,发现这种解决方法无法提供正确的建议(intellisense)。
Python中的一个问题是在同一个类中的函数参数类类型的使用。这个问题的原因是在Python 3.6及之前的版本中,没有提供forward引用的特性。然而,在Python 3.7中,forward引用特性被加入进来了(在PEP 563中)。所以现在可以这样使用:
from __future__ import annotations class C: def spam(self, other: C) -> C: pass
注意到了`__future__`语句的使用。在Python 3.7之前,这是必须的,直到4.0版本。不幸的是,在Python 3.6及之前的版本中,这个特性是不可用的,所以必须使用字符串注释,就像Jim Fasarakis Hilliard的回答中所解释的那样。
Mypy已经支持forward声明,即使在Python 3.6下运行也可以,但如果静态类型检查器说你的代码没问题,而解释器在实际运行时抛出NameError,那就没什么用了。
这种方法在我使用枚举类型(Enum)的时候非常有效。例如,对于一个具有枚举类型为`MyEnum(Enum)`的参数,我可以在函数中使用`my_arg: MyEnum`作为`MyEnum`枚举类型的参数。
Python - Function Parameter Class Type Within Same Class这个问题的出现的原因是,在编译类体时遇到Translate
时,Vector2
还没有被定义(它目前正在编译,尚未执行名称绑定)。因此,Python会自然地报错。为了解决这个常见的情况(在类的主体中对类进行类型提示),可以使用“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如何解析源代码的信息,请参考Eli Bendersky的文章。他撰写了一系列描述Python工作原理的好文章。您还可以阅读关于Python 3.5类型提示的文章,这些都是很好的信息来源。
总结一下,Python - Function Parameter Class Type Within Same Class这个问题的出现是因为在编译类体时,类的函数参数类型提示遇到了尚未定义的类,解决方法是使用前向引用将其引起来。Python 3.7之后的版本已经修复了这个问题。如果想了解更多关于Python如何解析源代码的信息,可以阅读Eli Bendersky的文章。