为了账号安全,请及时绑定邮箱和手机立即绑定

使用类作为其方法中参数的类型提示

使用类作为其方法中参数的类型提示

潇潇雨雨 2019-11-04 11:01:30
我下面包含的代码引发以下错误:NameError: name 'Vector2' is not defined 在这一行:def Translate (self, pos: Vector2):为什么Python无法Vector2在Translate方法中识别我的类?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
查看完整描述

2 回答

?
跃然一笑

TA贡献1826条经验 获得超6个赞

因为当它遇到时Translate(在编译类主体时),Vector2尚未被定义(当前正在编译中,尚未执行名称绑定);Python自然会抱怨。


由于这是一种常见的情况(在该类的主体中键入一个类的类型),因此应使用对它的前向引用,将其括在引号中:


class Vector2:    

    # __init__ as defined


    def Translate(self, pos: 'Vector2'):    

        self.x += pos.x

        self.y += pos.y

Python(以及所有符合的检查程序PEP 484)将理解您的提示并进行适当的注册。__annotations__通过typing.get_type_hints以下方式访问时,Python确实会识别出这一点:


from typing import get_type_hints


get_type_hints(Vector2(1,2).Translate)

{'pos': __main__.Vector2}


查看完整回答
反对 回复 2019-11-04
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

您要求的功能称为正向(类型)引用,并且从3.7(在PEP 563中)起已添加到Python中。1因此,这现在有效:


from __future__ import annotations

class C:

    def spam(self, other: C) -> C:

        pass

注意__future__声明。直到4.0才需要。


不幸的是,在Python 3.6及更早版本中,此功能不可用,因此您必须使用字符串注释,如Jim Fasarakis Hilliard的答案所述。


Mypy已经支持前向声明,即使在Python 3.6下运行时也是如此。但是,如果静态类型检查器说您的代码很好,但是NameError当您尝试实际运行它时,解释器会引发一个正向声明,这对您没有多大帮助。


1.这已在PEP 484中讨论为可能的功能,但在人们对在批注中使用前向声明有更多经验之后,将其推迟到以后。PEP 563 / Python 3.7就是“后来的”。


查看完整回答
反对 回复 2019-11-04
  • 2 回答
  • 0 关注
  • 516 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信