如何指定方法的返回类型与python中的类本身相同?
我在
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问题.它实际上使用其警告中的信息和代码完成 但如果我错了,请纠正我,并需要使用其他语法. 解决方法
TL; DR:如果您使用的是Python 4.0,它就可以了.从今天(2019年)的3.7开始,您必须使用将来的语句(来自__future__ import annotations)来启用此功能 – 对于Python 3.6或更低版本,请使用字符串.
我猜你有这个例外: NameError: name 'Position' is not defined 这是因为必须先定义Position,然后才能在注释中使用它,除非您使用的是Python 4. Python 3.7:来自__future__ import annotations Python 3.7引入了PEP 563: postponed evaluation of annotations.使用__future__ import annotations的future语句的模块将自动将注释存储为字符串: from __future__ import annotations class Position: def __add__(self,other: Position) -> Position: ... 这计划成为Python 4.0中的默认设置.由于Python仍然是动态类型语言,因此在运行时不进行类型检查,因此键入注释应该不会对性能产生影响,对吧?错误!在python 3.7之前,输入模块曾经是one of the slowest python modules in core,所以如果你导入输入,你会在升级到3.7时看到up to 7 times increase in performance. Python< 3.7:使用字符串 According to PEP 484,你应该使用一个字符串而不是类本身: class Position: ... def __add__(self,other: 'Position') -> 'Position': ... 如果你使用Django框架,这可能是熟悉的,因为Django模型也使用字符串作为前向引用(外键模型是自己的或未声明的外键定义).这应该适用于Pycharm和其他工具. 来源 PEP 484和PEP 563的相关部分,为您带来免费旅行:
class Tree: def __init__(self,left: Tree,right: Tree): self.left = left self.right = right
class Tree: def __init__(self,left: 'Tree',right: 'Tree'): self.left = left self.right = right
和PEP 563:
from __future__ import annotations 你可能想要做的事情 A.定义虚拟位置 在类定义之前,放置一个虚拟定义: class Position(object): pass class Position(object): ... 这将摆脱NameError甚至可能看起来不错: >>> Position.__add__.__annotations__ {'other': __main__.Position,'return': __main__.Position} 但是吗? >>> for k,v in Position.__add__.__annotations__.items(): ... print(k,'is Position:',v is Position) return is Position: False other is Position: False B.猴子补丁以添加注释: 您可能想尝试一些Python元编程魔术并编写装饰器 class Position: ... def __add__(self,other): return self.__class__(self.x + other.x,self.y + other.y) 装饰者应该负责相当于: Position.__add__.__annotations__['return'] = Position Position.__add__.__annotations__['other'] = Position 至少看起来是对的: >>> for k,v is Position) return is Position: True other is Position: True 可能太麻烦了. 结论 如果您使用的是3.6或更低版本,请使用包含类名的字符串文字,在3.7中使用__future__ import注释,它就可以正常工作. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |