如何指定方法的返回类型与类本身相同?

如何指定方法的返回类型与类本身相同?

我在python 3中有以下代码:

class Position:

    def __init__(self, x: int, y: int):
        self.x = x
        self.y = y    def __add__(self, other: Position) -> Position:
        return Position(self.x + other.x, self.y + other.y)

但是我的编辑器(PyCharm)说,无法解析引用位置(在__add__方法)。如何指定预期返回类型为Position?

编辑:我认为这实际上是一个PyCharm问题。它实际上使用警告和代码完成中的信息。

但是,如果我错了,需要使用其他语法来纠正我。


守着星空守着你
浏览 335回答 3
3回答

精慕HU

如果您使用的是Python4.0,那么它只是起作用了。从今天(2019年)开始,在3.7+中,您必须使用将来的语句(from __future__ import annotations)-对于Python3.6或更低的版本,请使用字符串。我想你有个例外:NameError:&nbsp;name&nbsp;'Position'&nbsp;is&nbsp;not&nbsp;defined这是因为Position除非使用Python 4,否则必须在注释中使用它之前定义它。Python 3.7+:from __future__ import annotationsPython 3.7Pep 563:推迟对说明的评价..使用未来语句的模块from __future__ import annotations将自动将注释存储为字符串:from&nbsp;__future__&nbsp;import&nbsp;annotationsclass&nbsp;Position: &nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;__add__(self,&nbsp;other:&nbsp;Position)&nbsp;->&nbsp;Position: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...这将成为Python4.0中的默认设置。因为Python仍然是一种动态类型语言,所以在运行时不进行类型检查,所以输入注释不应该对性能产生影响,对吗?不对!在python 3.7之前,类型模块以前是核心中最慢的python模块之一所以如果你import typing你会看到业绩提高7倍升级到3.7。Python<3.7:使用字符串根据PEP 484,您应该使用字符串而不是类本身:class&nbsp;Position: &nbsp;&nbsp;&nbsp;&nbsp;... &nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;__add__(self,&nbsp;other:&nbsp;'Position')&nbsp;->&nbsp;'Position': &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...如果您使用Django框架,这可能很熟悉,因为Django模型也使用字符串进行前向引用(外键定义,其中外接模型是self或尚未宣布)。这应该适用于PyCharm和其他工具。来源的相关部分佩普484和佩普563为了省去你的旅行:正向参考当类型提示包含尚未定义的名称时,该定义可以表示为字符串文本,待稍后解析。这种情况通常发生在容器类的定义上,其中定义的类发生在某些方法的签名中。例如,以下代码(简单二叉树实现的开始)无法工作:class&nbsp;Tree: &nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;__init__(self,&nbsp;left:&nbsp;Tree,&nbsp;right:&nbsp;Tree): &nbsp;&nbsp;&nbsp;&nbsp;self.left&nbsp;=&nbsp;left &nbsp;&nbsp;&nbsp;&nbsp;self.right&nbsp;=&nbsp;right为了解决这一问题,我们写道:class&nbsp;Tree: &nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;__init__(self,&nbsp;left:&nbsp;'Tree',&nbsp;right:&nbsp;'Tree'): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.left&nbsp;=&nbsp;left &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.right&nbsp;=&nbsp;right字符串文字应该包含一个有效的Python表达式(即编译(LIT,‘val’)应该是一个有效的代码对象),并且一旦模块被完全加载,它应该在没有错误的情况下进行计算。计算它的本地和全局命名空间应该是相同的名称空间,其中将计算相同函数的默认参数。和PEP 563:在Python4.0中,函数和变量注释将不再在定义时计算。相反,字符串窗体将保留在相应的__annotations__字典。静态类型检查器在行为上没有区别,而在运行时使用注释的工具将不得不执行延迟的评估。...可以使用以下特殊导入从Python3.7开始启用上面描述的功能:from&nbsp;__future__&nbsp;import&nbsp;annotations你可能会被诱惑去做的事情A.定义假人Position在类定义之前,放置一个虚拟定义:class&nbsp;Position(object): &nbsp;&nbsp;&nbsp;&nbsp;passclass&nbsp;Position(object): &nbsp;&nbsp;&nbsp;&nbsp;...这将消除NameError甚至看起来还可以:>>>&nbsp;Position.__add__.__annotations__{'other':&nbsp;__main__.Position,&nbsp;'return':&nbsp;__main__.Position}但是吗?>>>&nbsp;for&nbsp;k,&nbsp;v&nbsp;in&nbsp;Position.__add__.__annotations__.items():...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(k,&nbsp;'is&nbsp;Position:',&nbsp;v&nbsp;is&nbsp;Position)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;is&nbsp;Position:&nbsp;Falseother&nbsp;is&nbsp;Position:&nbsp;FalseB.为添加注释而进行的猴子补丁程序:您可能需要尝试一些Python元编程魔术,并编写一个修饰器来对类定义进行猴子修补,以便添加注释:class&nbsp;Position: &nbsp;&nbsp;&nbsp;&nbsp;... &nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;__add__(self,&nbsp;other): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;self.__class__(self.x&nbsp;+&nbsp;other.x,&nbsp;self.y&nbsp;+&nbsp;other.y)装修人员应对此负责:Position.__add__.__annotations__['return']&nbsp;=&nbsp;PositionPosition.__add__.__annotations__['other']&nbsp;=&nbsp;Position至少这似乎是对的:>>>&nbsp;for&nbsp;k,&nbsp;v&nbsp;in&nbsp;Position.__add__.__annotations__.items():...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(k,&nbsp;'is&nbsp;Position:',&nbsp;v&nbsp;is&nbsp;Position)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;is&nbsp;Position:&nbsp;Trueother&nbsp;is&nbsp;Position:&nbsp;True可能太麻烦了。结语如果使用3.6或更低版本,请使用包含类名的字符串文本,在3.7中使用from __future__ import annotations而且它会起作用的。

胡说叔叔

将类型指定为String是可以的,但总是会让我感到有些烦躁,因为我们基本上是在绕过解析器。所以你最好不要拼错这些文字字符串中的任何一个:def&nbsp;__add__(self,&nbsp;other:&nbsp;'Position')&nbsp;->&nbsp;'Position': &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Position(self.x&nbsp;+&nbsp;other.x,&nbsp;self.y&nbsp;+&nbsp;other.y)一个细微的变化是使用绑定的type var,至少在声明type var时,您必须只写一次字符串:from&nbsp;typing&nbsp;import&nbsp;TypeVarT&nbsp;=&nbsp;TypeVar('T',&nbsp;bound='Position')class&nbsp;Position: &nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;__init__(self,&nbsp;x:&nbsp;int,&nbsp;y:&nbsp;int): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.x&nbsp;=&nbsp;x &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.y&nbsp;=&nbsp;y&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;__add__(self,&nbsp;other:&nbsp;T)&nbsp;->&nbsp;T: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Position(self.x&nbsp;+&nbsp;other.x,&nbsp;self.y&nbsp;+&nbsp;other.y)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python