为什么包含类的名称不被识别为一个返回值的功能注释? [重复](Why is the name o

2019-08-18 13:35发布

这个问题已经在这里有一个答案:

  • 如何指定一个方法的返回类型是相同的类本身在Python? 3个回答

我打算用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_mapping(mapping) -> Trie:
NameError: name 'Trie' is not defined

值得一提的是,如果一个基本类型(比如这个错误不会发生objectint )或标准库类型(如collections.deque指定)。

是什么原因造成这个错误,我该如何解决?

Answer 1:

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


Answer 2:

Trie是有效的表达式,并评估与名称名称相关联的电流值Trie 。 但是,这名未被定义尚未-类主体已运行到completition 一类对象只绑定至名归。 你会注意到在这个非常简单的例子相同的行为:

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__)

觉得相当哈克虽然。 根据您的使用情况下,有可能改为使用定点对象(例如CONTAINING_CLASS = object()并留下解释的是到任何实际处理注释。



文章来源: Why is the name of the containing class not recognized as a return value function annotation? [duplicate]