Class `for`...`if` 表达式中的变量在 python 中失败

Class variable in `for`...`if` expression fails in python

使用这个简单的代码:

class A(object):
  numbers = [1, 2, 3]
  numberscopy = numbers[:]
  print(*(a for a in numberscopy))
  print(*(a for a in numberscopy if a in numbers))

我在 class 中定义了 numbers 变量。然后我可以用它做其他事情,比如制作副本、遍历它并打印它的内容。

但最后一行 for-if 语句失败并显示 NameError: global name 'numbers' is not defined。不是 numberscopy,只是 numbers.

我尝试了 python 2.7.14+(导入了 print_function)和 3.7.0,结果相同。

为什么会这样?它打算以这种方式工作吗?

class-bodies 中的代码在 Python 中有些混乱。这不是一个错误,而是一个 "implementation problem that got weird".

问题在于:代码通常 运行 在模块级别或函数内部 - 当在函数内部时,有 well-defined "local" 个变量。

class 主体中的代码也 运行 具有 "local" 作用域 - 但是如果创建的函数是 运行 而 class 主体正在处理过的,这些不 "see" outer-level 个变量。和生成器表达式一样,推导式也是如此(在 Python 3 中,Python 2 是另一种语言,它即将淘汰,让我们不要把事情复杂化)。用于在生成器内部创建指向 for 的迭代器的表达式在 "sees" 外部变量的范围内是 运行。主表达式和 if 表达式本身在生成器内部,不能 "see" 那些变量。

因此,如果在 class 主体内 需要 理解,则解决方法是在 class 主体内设置一个中介函数,以生成您需要的值和变量,并有一行来调用它并使用该内部函数的本地名称空间更新 class 自己的变量:

class A:
   def create_vals():
       numbers = [1, 2, 3]
       numbers_copy = numbers[:]
       values = list(a for a in numbers if a in numbers_copy)
       return locals()
   locals().update(create_vals())
   del create_vals

因此,在临时 create_vals 函数(它不是方法)中,通常的 scope-nesting 规则适用 - 最后两行我们将创建的变量复制到 class 本身,并删除临时函数。