Python 使用方法理解列表中的评估范围
我对列表理解和Python 使用方法理解列表中的评估范围,python,function,list-comprehension,eval,Python,Function,List Comprehension,Eval,我对列表理解和eval语句相结合的方法感到困惑。test7行中的以下代码出现错误,错误为NameError:name“a2” class test_class(object): def __init__(self): pass @property def property(self): return 'test_method_run' def run(): a2 = test_class() test3 = eval('a
eval
语句相结合的方法感到困惑。test7行中的以下代码出现错误,错误为NameError:name“a2”
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()
它一定与scope()有关。我对Python2中作用域的理解(我刚刚转到Python3)是a
不应该在run()
中定义,而a2
是。列表理解的影响使我更加困惑。我的期望是test2
和test3
行应该失败,因为a
没有使用test
方法定义。我还希望如果test5
运行正常,那么test6
和test7
也应该可以
只有在函数中的列表理解中使用了eval
时,才会发生此错误。。。如果这3个元素中的任何一个不存在,则没有错误。我的问题是为什么?我觉得我没有足够的理解来形成一个更好的问题
我对Python2中的作用域的理解(我刚刚转到Python3)是不应该在run()中定义a,而应该在a2中定义
a
和a2
都可以从run
中看到a
是在全局范围内定义的,因此它在该文件中的任何位置都可见
我希望如果test5运行正常,那么test6和test7也应该正常
在3.X中,列表理解有自己的范围。test6列表理解可以访问三个范围:列表理解范围、函数范围和全局范围。因此它可以访问i
和a2
和a
默认情况下,在eval
中执行的代码可以访问两个作用域:全局作用域和最近的局部作用域。这意味着test7
eval可以访问文件级定义的变量,也可以访问列表理解内部定义的变量,但不能访问函数内部定义的变量,只能访问列表理解外部的变量。它可以看到a
和i
,但不能看到a2
在2.7中,列表理解没有自己的范围。它们与在中定义的函数共享相同的作用域。这解释了为什么代码在2.7中执行,而不是在3.X中执行。IIRC,这是范围系统在2.7和3.X之间的唯一变化。(如果不是,这是唯一与此场景相关的更改。)Python 3中作用域的另一个更改是
非局部
语句的可用性,它允许内部函数修改外部函数作用域中定义的变量。但正如你所说,这与这个问题无关。