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 本身,并删除临时函数。
使用这个简单的代码:
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 本身,并删除临时函数。