在Python3.6中,该语言引入了新的Variable Annotations.

但是,当一种类型不存在时,可能会发生两种不同的情况:

>>> def test():
...     a: something = 0
... 
>>> test()
>>> 
>>> a: something = 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'something' is not defined

为什么不存在的类型处理行为不同?这难道不会导致人们忽略函数中未定义的类型吗?


Notes

在Python3.6 RC1和RC2上都try 过——行为相同.

PyCharm在函数内部和外部都突出显示something为"未解析引用".

推荐答案

局部变量(即函数内部)的行为至少记录在第Runtime Effects of Type Annotations节:

注释局部变量会导致解释器将其视为局部变量,即使它从未被赋值.不计算局部变量的注释:

def f():
    x: NonexistentName  # No error.

接着解释了全局变量的差异:

但是,如果是在模块或类级别,则将判断该类型:

x: NonexistentName  # Error!
class X:
    var: NonexistentName  # Error!

这种行为对我来说似乎很奇怪,所以我只能猜测其原因:如果我们将代码放在一个模块中,那么Python希望存储注释.

# typething.py
def test():
    a: something = 0

test()


something = ...

a: something = 0

然后导入它:

>>> import typething
>>> typething.__annotations__
{'a': Ellipsis}
>>> typething.test.__annotations__
{}

为什么有必要将其存储在模块对象上,而不是函数对象上——我还没有一个好的答案.可能是出于性能原因,因为注释是通过静态代码分析生成的,这些名称可能会动态更改:

...注释在本地可用的价值并不能抵消每次函数调用时创建和填充注释字典的成本.因此,不会计算和存储函数级别的注释.

Python-3.x相关问答推荐

需要使用regex匹配字符串的帮助,直到最后一次出现开闭括号,开闭括号中的值是可选的

Pandas 根据条件增加Dataframe列

AddMultplicationEquality() 用于多个变量

向前/向后移动导致移动行的数据不可见

Django 模型类方法使用错误的 `self`

如何获取实例化 `types.GenericAlias` 的下标类?

Python中提取每个组/ID所属特定列中的自然数

如何将 WebDriver 传输到导入的测试?

单击图形时 plotly graph_objects 持久性数据

pytorch 中 mps 设备的 manual_seed

如何使用复选按钮更改 Pyplot 轴的属性?

如何使用`re.findall`从字符串中提取数据

FastAPI - 调用 API 时设置 response_model_exclude

Semaphore信号量 Python 的工作原理

命名元组内命名元组的 Python 语法

UnicodeDecodeError:utf-8编解码器无法解码位置 1 的字节 0x8b:无效的起始字节,同时读取Pandas中的 csv 文件

asyncio.Semaphore RuntimeError: Task got Future 附加到不同的循环

作为函数对象属性的 __kwdefaults__ 有什么用?

如何将numpy数组图像转换为字节?

如何在继承的数据类中创建可选字段?