为什么带注释的变量不能是全局变量?

17

运行中

def function():
    global global_values
    global_values: str = []

提供

SyntaxError: annotated name 'global_values' can't be global

这是有什么原因吗?

当我在函数内使用global类型注释时,我遇到了相同的错误。将类型注释放在全局空间中解决了这个问题。PS:在我的设置中执行您提出的Python 3.8.8代码行不会生成任何错误。 - Mike
@Mike 我在全局空间中使用类型注释并在函数内部使用global语句时遇到了SyntaxError。在Python 3.10中,我也遇到了同样的错误。我认为OP应该将该语句放在一个函数内部(因为在全局空间中使用global关键字是没有意义的)。 - PythoNic
3个回答

11

这在PEP-526中已经有所解释:

在同一函数范围内尝试注释受globalnonlocal约束的变量是非法的:

def f():
    global x: int  # SyntaxError

def g():
    x: int  # Also a SyntaxError
    global x

原因是globalnonlocal不拥有变量;因此,类型注释应该属于拥有变量的作用域。
解决方案是在函数之外(即全局命名空间)注释变量,并在函数作用域内删除类型注释。

4
这是什么意思?那么你如何为全局变量添加注释? - uchuugaka
1
@uchuugaka 这意味着你唯一可以注释全局变量的地方是在它自己的作用域内,即全局作用域。 - Whole Brain

7
因为通常情况下,对于非常“老”的语言特性,这很令人困惑。 在Python中,global是一个语句,声明一个名称globals()类似字典容器中的键相匹配。 如果该键尚未存在于globals()类似字典容器中,则将添加该键,并在那时默认设置为None。 如果在全局范围内分配了一个变量(并在那时定义),则将该变量的 名称添加到globals()类似字典容器中,并将 设置为与名称匹配的键的值在globals()类似字典容器中。
因此,global关键字是一种语句,将名称添加到globals()类似字典容器中。 不幸的是,您无法在与使用global添加该变量名称到globals()类似字典容器相同的行中对该变量进行赋值。
由于这个悲伤的原因,将名称添加到globals()类似字典容器将隐式地使其成为Python类型体系中的可选类型。
我仍然认为这是一种思维上的错误。它不明显,不清晰,也不真正合理。然而,它就在那里。
正确的做法应该是在将变量设置为全局变量时立即对其赋值,从而拥有非可选的全局类型,并消除这种难以理解和烦人的边缘情况。类型很棒,希望在Python中拥有更多它。它有助于扩展,有助于消除导致困难错误的逻辑错误和模棱两可的情况。它还强调了您可能未考虑到的变量可能是与编写的代码完全不兼容的类型的情况。

这是一个边缘情况吗?感谢您的好回答。 - isomorphismes

1
所给出的被接受答案的解释根本没有任何意义,而且在这个讨论中似乎对于“应该允许”对全局变量进行注释已经达成共识:https://bugs.python.org/issue34939,但是到目前为止——Python 3.8——它还没有被实现。问题必须在实现方面出了问题,而不是逻辑上的问题。

我不同意接受的答案毫无意义这一说法——它确实有意义,并且回答了 OP 的使用情况。尽管如此,你提到的 bug 链接实际上正是我正在寻找的,因为我有一些在 Python 3.9.7 中运行但在 3.7.8 中显示出相同 bug 的代码。但导致该 bug 的情况与 OP 的问题不同。 - pogojotz
3
被接受的答案是引用,而不是错误的解释。 - uchuugaka
@uchuugaka 是的,被接受的答案引用了一个解释,而我的答案则说给出的那个引用的解释没有逻辑意义。我还提供了一个链接给那些正在处理这个“错误”的人,即全局变量无法注释的问题。 - j4hangir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接