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

为什么包含类的名称不能被识别为返回值函数注释?[重复]

董联
2023-03-14

我打算使用Python函数注释来指定静态工厂方法返回值的类型。我知道这是注释所需的用例之一。

class Trie:
    @staticmethod
    def from_mapping(mapping) -> Trie:
        # docstrings and initialization ommitted
        trie = Trie()
        return trie

PEP 3107规定:

函数注释只不过是在编译时将任意Python表达式与函数的各个部分关联起来的一种方式。

Trie是Python中有效的表达式,不是吗?Python不同意,或者更确切地说,找不到名字:

def from_映射(映射)-

值得注意的是,如果指定了基本类型(如objectint)或标准库类型(如collections.deque),则不会发生此错误。

导致此错误的原因是什么?如何修复?


共有2个答案

景理
2023-03-14

PEP 484以前向引用的形式提供了对此的官方解决方案。

当类型提示包含尚未定义的名称时,该定义可以表示为字符串文字,稍后解析。

对于问题代码:

class Trie:
    @staticmethod
    def from_mapping(mapping) -> Trie:
        # docstrings and initialization ommitted
        trie = Trie()
        return trie

变成:

class Trie:
    @staticmethod
    def from_mapping(mapping) -> 'Trie':
        # docstrings and initialization ommitted
        trie = Trie()
        return trie
郎星汉
2023-03-14

Trie是有效的表达式,计算结果为与名称Trie关联的当前值。但是这个名称还没有定义——类对象只有在类主体运行到completion之后才绑定到它的名称。在这个简单得多的示例中,您将注意到相同的行为:

class C:
    myself = C
    # or even just
    C

通常,解决方法是在类定义后在类主体之外设置类属性。这不是一个非常好的选择,尽管它很有效。或者,您可以在初始定义中使用任何占位符值,然后在__annotations__中替换它(这是合法的,因为它是一个常规字典):

class C:
    def f() -> ...: pass
print(C.f.__annotations__)
C.f.__annotations__['return'] = C
print(C.f.__annotations__)

但它确实让人觉得有点不舒服。根据您的用例,可能会使用sentinel对象(例如包含_CLASS=object())并将其解释留给实际处理注释的任何人。

 类似资料:
  • 场景1--Case类 Astyanax无法在上获取注释@id 场景2-有伴生对象的类或无伴生对象的类 除了#3,我在类块中声明了一个val,而不是case类或常规类/常规类的参数列表,我的每个场景都失败了。Astyanax说,该类中有一个know成员用注释,所以它会抛出异常。在我进一步挖掘之前,我想我应该询问社区关于注释scala类和将其发送到执行反射的java库之间的细微差别。来源没有什么特别的

  • 问题内容: 我有一个箭头函数,看起来像这样(简化): 但是当我调用它时,我得到: 为什么? 例: ( 注意: 对于上述带有箭头功能的 特定 问题,这是一个干净,规范的重复目标。) 问题答案: 当您使用箭头函数的函数主体版本(带有)时,没有暗示。您必须指定它。当您使用 简洁 主体(no )时,主体表达式的结果将由函数隐式返回。 因此,您可以使用显式的方式编写该代码: 或简洁的主体: 例子: 略 切线

  • 问题内容: 我正在编写一段代码,如果它是某个类的实例,则必须在其中强制转换。 和往常一样,我用于检查兼容性。 问题在于,由于对象属于“奇怪”类,因此永远无法满足检查要求。 例如; 当我在此对象上调用方法时,它将返回类+的名称(例如而不是)。 这是什么意思?有解决方案或解决方法吗? 问题答案: 那显示一个 内部类 (匿名(如果有数字)或命名)。例如: 班级的名称是。现在,如果我们有: 那将打印出来。

  • 我正在编写一段代码,如果对象是某个类的实例,我必须在其中强制转换它。 像往常一样,我使用检查兼容性。 问题是检查永远不会满足,因为对象属于“奇怪”类。 例如当我调用方法在这个对象上,它返回类的名称(例如而不是)。 这是什么意思?是否有解决方案或解决方法?

  • 问题内容: 我是一名编程初学者,对函数的返回值有疑问。 我正在学习Java。 我已经附上了我的书中具有经典选择排序功能的代码。 现在显然来自本书的代码可以正常工作。但是,主要功能中的以下三行是我的问题的基础: int [] a = new int [] {1,9,2,8,3,7,4,6​​,5}; 排序(a); if(ascending(a))System.out.println(“ Works”

  • 我对编码很陌生,遇到了这个问题,不知道如何解决它,我见过类似的问题,但是,我只是不能理解其中的大多数。我已经尝试添加路径几次,甚至重新安装了Vscode,它似乎无法解决。 我写的代码:: 我得到的错误是: 我试过了: 1:再次设置路径 2:重新安装与代码。 任何类型的信息都会真正有所帮助,因此我无法再进步了。