使用类作为其方法中参数的类型提示[重复]

Posted

技术标签:

【中文标题】使用类作为其方法中参数的类型提示[重复]【英文标题】:Using the class as a type hint for arguments in its methods [duplicate] 【发布时间】:2017-02-24 05:33:09 【问题描述】:

我在下面包含的代码会引发以下错误:

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

【问题讨论】:

【参考方案1】:

因为在遇到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 开始更改;见abarnert's answer below。

【讨论】:

您能否为我提供一个很好的信息来源,更多地涉及 Python 如何遍历我的来源?当 Python 尚未定义我的类时,当它通过我的同一个类的实例方法时,我很感兴趣。 @Vanitas Hm,您可以查看查看类定义的Eli Bendersky's article。他通常写了一组很好的文章来描述 Python 是如何做事的。 快速阅读了 Eli Bendersky 的文章和其他一些文章,还找到了您关于 Python 3.5 中的类型提示的文章。我会好好阅读文章,谢谢分享。 :)【参考方案2】:

您要求的功能称为前向(类型)引用,它已从 3.7 开始添加到 Python(PEP 563)。1 所以现在有效:

from __future__ import annotations
class C:
    def spam(self, other: C) -> C:
        pass

注意__future__ statement。这将是必要的until 4.0。

很遗憾,在 Python 3.6 及更早版本中,此功能不可用,因此您必须使用字符串注释,如 Jim Fasarakis Hilliard's answer 中所述。

Mypy 已经支持前向声明,即使在 Python 3.6 下运行时也是如此——但如果静态类型检查器说你的代码没问题,但解释器在你尝试实际运行它时会引发 NameError,这对你没有多大好处.


1。这已经在PEP 484 中作为一个可能的特性进行了讨论,但推迟到后来人们在注释中使用前向声明有更多经验之后。 PEP 563/Python 3.7 是“以后”。

【讨论】:

【参考方案3】:

也许另一种选择是先定义类,但实现为空。我想最常见的解决方案是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

【讨论】:

以上是关于使用类作为其方法中参数的类型提示[重复]的主要内容,如果未能解决你的问题,请参考以下文章

类型提示:类型类的参数 [重复]

在 C# 中使用枚举作为泛型类型参数 [重复]

Java中的通用方法-如何将参数类类型作为返回类型返回[重复]

在swift中使用类类型变量作为函数参数[重复]

使用类自变量作为默认类方法参数[重复]

传递方法作为参数[重复]