当前位置: 首页 > 知识库问答 >
问题:

将类用作其方法中参数的类型提示[duplicate]

夹谷斌蔚
2023-03-14

下面包含的代码抛出以下错误:

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

共有3个答案

龙高歌
2023-03-14

也许另一种选择是以前定义类,用一个空的实现。我想最常见的解决方案是前向引用,但我的建议是更安全的类型,毕竟这是添加类型的目的。

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
袁雅逸
2023-03-14

您要求的特性称为前向(类型)引用,并且从3.7开始(在PEP 563中)它就被添加到Python中1因此这现在是有效的:

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

请注意\uuuuuuuuuuuuuuu语句。这在4.0之前是必需的。

不幸的是,在Python3.6和更早版本中,此功能不可用,因此必须使用字符串注释,正如Jim Fasarakis Hilliard的回答中所解释的那样。

Mypy已经支持转发声明,即使在Python3.6下运行,但是如果静态类型检查器说您的代码很好,但是当您尝试实际运行它时,解释器会引发一个NameError,这对您没有多大好处。

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

戴原
2023-03-14

因为当它遇到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}

从Python 3.7开始,这已经改变了;见下面abarnert的回答。

 类似资料:
  • 我试图在Python3.5中使用类型提示。1,代码如下: 我猜在解析类型A时,类型A还没有完全构造,这是范围界定的问题,但我不理解为什么这样的语法不正确。是否有其他方式来表达它,或者它只是一个非法的构造? 我想在基类中使用这个语法提示,它可以在树状层次结构中组成派生类。

  • 问题内容: 问题摘要: 我想将具有类型参数(例如)的类作为类型参数传递给泛型方法。 假设我有一个方法: 当然,此方法对于任何类型的类都可以正常使用。我可以这样调用该方法,例如: 问题: 我发现我不能这样做: 从句法上讲,这显然是无效的。但是,我不确定如何实现这样的目标。我当然可以通过,但是泛型类型的添加使其在语法上不再有效,并且我想不出解决方法。 唯一的直接解决方案是这样的事情(看起来很愚蠢):

  • 我使用的是Azure.data.tables nuget包的12.0.0-beta.6。当我尝试调用TableClient.GetQueryAsync时,它会给出错误: “类型”T“必须是引用类型,才能将其用作泛型类型或方法”TableClient.GetEntityAsync(string,string,IEnumerable,CancellationToken)“中的参数”T“。” 我看不出我

  • 问题内容: 您认为可以创建类似的东西吗? 问题答案: 是的你可以。 用法示例:

  • 问题内容: class Node: def append_child(self, node: Node): if node != None: self.first_child = node self.child_nodes += [node] 我该怎么办?因为当我运行它时,它说。 我应该只删除and实例在函数中检查它吗?但是,我该如何访问的属性(我希望它是类的实例)? 我不知道如何在Python,

  • 我正在使用 我得到以下错误 错误CS0453类型“MyObject”必须是不可为空的值类型,才能将其用作泛型类型或方法“Nullable”中的参数“T” 我也试过 如果我将其设置为可为null,那么为什么我会在方法名称下面得到带有此错误消息的红线 stackoverflow的答案很简单,将返回类型设为null,但对我来说Visual studio不允许这样做。