名称未在类型注释中定义 [英] Name not defined in type annotation

查看:52
本文介绍了名称未在类型注释中定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在创建一个 Python 线性代数模块,以供娱乐和使用该语言进行练习.我最近尝试向模块添加类型注释,例如:

I'm currently working on creating a python linear algebra module for fun and for practice with the language. I recently tried to add type annotations to the module, as such:

class Vector:
     # Various irrelevant implementation details
     def __add__(self, other: Vector) -> Vector:
        # More implementation details....

但是,当我尝试导入它时,它会吐出一个NameError: Name 'Vector' is not defined.我承认这个问题已经以一种形式得到了回答,这里,但它似乎并没有完全为我的情况提供答案.

However, when I try to import this, it spits out a NameError: Name 'Vector' is not defined. I acknowledge that this question has already been answered, in a form, here, but it doesn't seem to wholly provide an answer for my situation.

我想知道的:

  • 我已经在这个文件中逐字定义了这个类.为什么它说名称未定义?
  • 如何定义 Vector 使其可用于注释(作为 type)?
  • I've defined the class literally in this file. Why does it say the name isn't defined?
  • How do I define Vector in such a way that it can be used for annotations (as a type)?

推荐答案

您有一个前置声明;函数(被绑定为方法)在类创建之前被创建,所以名称 Vector 还不存在.只有当所有的类体都执行完毕后,Python 才能创建class 对象并将名称Vector 绑定到它.

You have a forward declaration; functions (to be bound as methods) are created before the class is, so the name Vector doesn't yet exist. Only when all of the class body has been executed, can Python create the class object and bind the name Vector to it.

只需使用带有名称的字符串即可:

Simply use a string with the name instead:

class Vector:
     # Various irrelevant implementation details
     def __add__(self, other: 'Vector') -> 'Vector':
        # More implementation details....

这不会影响您的 IDE 如何看待声明;一旦加载了整个模块,就会查找字符串,并在当前上下文中将其解析为有效的 Python 表达式.由于类Vector在整个模块加载后就存在,字符串'Vector'可以正确地转换为类对象.

This doesn't affect how your IDE sees the declaration; strings are looked up once the whole module is loaded, and are resolved as a valid Python expression in the current context. Since the class Vector exists once the whole module is loaded, the string 'Vector' can properly be converted to the class object.

另请参阅关于前向引用的规范:

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

When a type hint contains names that have not been defined yet, that definition may be expressed as a string literal, to be resolved later.

[...]

字符串文字应该包含一个有效的 Python 表达式 [...],并且一旦模块完全加载,它应该评估没有错误.

The string literal should contain a valid Python expression [...] and it should evaluate without errors once the module has been fully loaded.

从 Python 3.7 开始,您可以通过在顶部添加 from __future__ import annotations 指令,使给定模块中的所有注释的行为类似于前向注释(无需将它们包含在字符串文字中)模块.在 Python 3.10 及更高版本 这已成为默认行为.请参阅PEP 563 -- 注释的推迟评估.请注意,在注释的之外,您可能仍需要使用前向引用语法(字符串文字),例如在类型别名中(就 Python 而言,这是一个常规的变量赋值).

As of Python 3.7 you can make all annotations in a given module behave like forward annotations (without enclosing them in a string literal), by adding the from __future__ import annotations directive at the top of the module. In Python 3.10 and up this has become the default behaviour. See PEP 563 -- Postponed Evaluation of Annotations. Note that outside of annotations you may still need to use forward reference syntax (string literals), e.g. in a type alias (which is a regular variable assignment as far as Python is concerned).

这篇关于名称未在类型注释中定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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