为什么包含类的名称不被识别为一个返回值的功能注释? [英] Why is the name of the containing class not recognized as a return value function annotation?

查看:139
本文介绍了为什么包含类的名称不被识别为一个返回值的功能注释?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要使用 Python函数注释来指定静态工厂方法的返回值的类型。我明白这是所需要的用例之一的注解。

I was going to use Python function annotations to specify the type of the return value of a static factory method. I understand this is one of the desired use cases for annotations.

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

PEP 3107 指出:

功能注释只不过是在编译时关联任意Python前$ P $与函数的各个部分pssions的一种方式了。

Function annotations are nothing more than a way of associating arbitrary Python expressions with various parts of a function at compile-time.

特里是在Python有效的前pression,不是吗? Python不同意或者说,找不到名称:

Trie is a valid expression in Python, isn't it? Python doesn't agree or rather, can't find the name:

高清from_mapping(映射) - >特里:结果
    NameError:名称'特里'没有定义

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

It's worth noting that this error does not happen if a fundamental type (such as object or int) or a standard library type (such as collections.deque) is specified.

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

推荐答案

特里是一个有效的前pression,并评估与此名称相关的当前值名称特里。但是,这名未被定义,然而 - 一类对象的 的类主体已运行completition后只绑定至名归。你会注意到在这个非常简单的例子相同的行为:

Trie is a valid expression, and evaluates to the current value associated with the name name Trie. But that name is not defined yet -- a class object is only bound to its name after the class body has run to completition. You'll note the same behavior in this much simpler example:

class C:
    myself = C
    # or even just
    C

通常情况下,解决方法是设置类已经被定义之后,类主体以外的类属性。这不是一个很好的选择在这里,虽然它的工作原理。或者,您可以在初始定义中使用的任何占位符值,然后替换它在 __注释__ (这是合法的,因为这是一个普通的字典):

Normally, the workaround would be setting the class attribute after the class has been defined, outside the class body. This is not a really good option here, though it works. Alternatively, you could use any placeholder value in the initial definition, then replace it in the __annotations__ (which is legal because it's a regular dictionary):

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

它的确实的感觉,而哈克虽然。根据您的使用情况下,有可能改为使用定点对象(如 CONTAINING_CLASS =对象()),并离开国际preting,要什么实际处理注释。

It does feel rather hacky though. Depending on your use case, it might be possible to instead use a sentinel object (e.g. CONTAINING_CLASS = object()) and leave interpreting that to whatever actually processes the annotations.

这篇关于为什么包含类的名称不被识别为一个返回值的功能注释?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆