使用方法的列表理解中的 eval 范围
Scope within eval in list comprehension with method
我对结合列表理解和 eval
语句的方法感到困惑。下面的代码在 test7 行出错,错误为 NameError: name 'a2' is not defined
。
class test_class(object):
def __init__(self):
pass
@property
def property(self):
return 'test_method_run'
def run():
a2 = test_class()
test3 = eval('a.property')
test4 = [eval('a.property') for i in range(10)]
test5 = eval('a2.property')
test6 = [a2.property for i in range(10)]
test7 = [eval('a2.property') for i in range(10)
a = test_class()
test1 = eval('a.property')
test2 = [eval('a.property') for i in range(10)]
run()
一定和作用域有关()。我对 python 2 中范围的理解(我刚刚转到 python 3)是 a
不应在 run()
中定义,但 a2
是。我对列表理解的影响感到更加困惑。我的期望是 test2
和 test3
行应该失败,因为 a
没有用 test
方法定义。我还预计,如果 test5
运行正常,那么 test6
和 test7
也应该没问题。
只有在函数内的列表推导中使用 eval
时才会出现此错误...如果这 3 个元素中的任何一个不存在,则不会出现错误。我的问题是为什么?我觉得我对它的理解还不足以形成一个更好的问题。
My understanding of scope in python 2 (I have just moved to python 3) was that a should not be defined within run(), but a2 is.
a
和 a2
都在 run
中可见。 a
是在全局范围内定义的,因此它在该文件中随处可见。
I expected that if test5 runs OK then test6 and test7 should also be fine.
在 3.X 中,列表解析有自己的作用域。 test6 列表理解可以访问三个范围:列表理解的范围、函数的范围和全局范围。所以它可以访问 i
和 a2
以及 a
.
默认情况下,在 eval
内执行的代码可以访问两个范围:全局范围和最近的本地范围。这意味着 test7
eval 可以访问在文件级别定义的变量,它可以访问列表推导内部定义的变量,但它不能访问函数内部但列表推导之外定义的变量。它可以看到 a
和 i
但看不到 a2
.
在 2.7 中,列表推导没有自己的作用域。它们与它们在其中定义的函数共享相同的作用域。这解释了为什么您的代码在 2.7 中执行而不在 3.X 中执行。 IIRC,这是 2.7 和 3.X 之间范围系统的唯一变化。 (如果不是,这是与此场景相关的唯一更改。)
我对结合列表理解和 eval
语句的方法感到困惑。下面的代码在 test7 行出错,错误为 NameError: name 'a2' is not defined
。
class test_class(object):
def __init__(self):
pass
@property
def property(self):
return 'test_method_run'
def run():
a2 = test_class()
test3 = eval('a.property')
test4 = [eval('a.property') for i in range(10)]
test5 = eval('a2.property')
test6 = [a2.property for i in range(10)]
test7 = [eval('a2.property') for i in range(10)
a = test_class()
test1 = eval('a.property')
test2 = [eval('a.property') for i in range(10)]
run()
一定和作用域有关(a
不应在 run()
中定义,但 a2
是。我对列表理解的影响感到更加困惑。我的期望是 test2
和 test3
行应该失败,因为 a
没有用 test
方法定义。我还预计,如果 test5
运行正常,那么 test6
和 test7
也应该没问题。
只有在函数内的列表推导中使用 eval
时才会出现此错误...如果这 3 个元素中的任何一个不存在,则不会出现错误。我的问题是为什么?我觉得我对它的理解还不足以形成一个更好的问题。
My understanding of scope in python 2 (I have just moved to python 3) was that a should not be defined within run(), but a2 is.
a
和 a2
都在 run
中可见。 a
是在全局范围内定义的,因此它在该文件中随处可见。
I expected that if test5 runs OK then test6 and test7 should also be fine.
在 3.X 中,列表解析有自己的作用域。 test6 列表理解可以访问三个范围:列表理解的范围、函数的范围和全局范围。所以它可以访问 i
和 a2
以及 a
.
默认情况下,在 eval
内执行的代码可以访问两个范围:全局范围和最近的本地范围。这意味着 test7
eval 可以访问在文件级别定义的变量,它可以访问列表推导内部定义的变量,但它不能访问函数内部但列表推导之外定义的变量。它可以看到 a
和 i
但看不到 a2
.
在 2.7 中,列表推导没有自己的作用域。它们与它们在其中定义的函数共享相同的作用域。这解释了为什么您的代码在 2.7 中执行而不在 3.X 中执行。 IIRC,这是 2.7 和 3.X 之间范围系统的唯一变化。 (如果不是,这是与此场景相关的唯一更改。)