首先,请注意,这与其他有关exec内部变量的SO问题不同。这对于执行程序中列表理解 TEST 中使用的变量是个问题。
参加此test.py:
myglob_var = 'my global var'
def myfunc():
s = """
print('myglob_var =',myglob_var)
users = ['root','service']
flag = True
c_list = [ u for u in users ]
print('list comprehension =',c_list)
c_list_with_test = [ u for u in users if flag ]
print('list comprehension with test =',c_list_with_test)
some_result = 'a result'
"""
exec(s)
myfunc()
执行时我有这个:
$ python3 test.py
myglob_var = my global var
list comprehension = ['root', 'service']
Traceback (most recent call last):
File "test.py", line 18, in <module>
myfunc()
File "test.py", line 15, in myfunc
exec(s)
File "<string>", line 7, in <module>
File "<string>", line 7, in <listcomp>
NameError: name 'flag' is not defined
users
和flag
都在exec()中定义。两者都用于列表理解。但只有flag
被视为未定义,因为它在测试中使用。
我可以使用exec(s,globals())
解决此问题:
myglob_var = 'my global var'
def myfunc():
s = """
print('myglob_var =',myglob_var)
users = ['root','service']
flag = True
c_list = [ u for u in users ]
print('list comprehension =',c_list)
c_list_with_test = [ u for u in users if flag ]
print('list comprehension with test =',c_list_with_test)
some_result = 'a result'
"""
exec(s, globals())
print('some_result as global var =',globals().get('some_result'))
print('some_result as local var =',locals().get('some_result'))
myfunc()
执行时我得到:
$ python3 test.py
myglob_var = my global var
list comprehension = ['root', 'service']
list comprehension with test = ['root', 'service']
some_result as global var = a result
some_result as local var = None
一切都很好,但我希望some_result
是本地的,而不是全局的。
为此,我使用了另一个关于SO的问题的配方:
myglob_var = 'my global var'
def myfunc():
s = """
print('myglob_var =',myglob_var)
users = ['root','service']
flag = True
c_list = [ u for u in users ]
print('list comprehension =',c_list)
c_list_with_test = [ u for u in users if flag ]
print('list comprehension with test =',c_list_with_test)
some_result = 'a result'
"""
nm = {}
exec(s, globals(), nm)
print('Result =',nm.get('some_result'))
myfunc()
,但flag
上的未定义再次出现:
$ python3 test.py
myglob_var = my global var
list comprehension = ['root', 'service']
Traceback (most recent call last):
File "test.py", line 18, in <module>
myfunc()
File "test.py", line 15, in myfunc
exec(s, globals(), nm)
File "<string>", line 7, in <module>
File "<string>", line 7, in <listcomp>
NameError: name 'flag' is not defined
编辑:
我可以这样解决:
myglob_var = 'my global var'
def myfunc():
s = """
print('myglob_var =',myglob_var)
users = ['root','service']
flag = True
c_list = [ u for u in users ]
print('list comprehension =',c_list)
c_list_with_test = [ u for u in users if flag ]
print('list comprehension with test =',c_list_with_test)
some_result = 'a result'
"""
nm = globals().copy()
exec(s, nm)
print('Result =',nm.get('some_result'))
myfunc()
我明白了:
myglob_var = my global var
list comprehension = ['root', 'service']
list comprehension with test = ['root', 'service']
Result = a result
看起来不错,除了在我的实际应用程序中,变量赋值在exec之前:
myglob_var = 'my global var'
def myfunc():
flag = True
users = ['root','service']
s = """
print('myglob_var =',myglob_var)
c_list = [ u for u in users ]
print('list comprehension =',c_list)
c_list_with_test = [ u for u in users if flag ]
print('list comprehension with test =',c_list_with_test)
some_result = 'a result'
"""
nm = globals().copy()
exec(s, nm, locals())
print('Result =',nm.get('some_result'))
myfunc()
这一次,它再次触发了相同的问题:exec中定义了users
,但没有flag
:
$ python3 test.py
myglob_var = my global var
list comprehension = ['root', 'service']
Traceback (most recent call last):
File "test.py", line 19, in <module>
myfunc()
File "test.py", line 15, in myfunc
exec(s, nm, locals())
File "<string>", line 5, in <module>
File "<string>", line 5, in <listcomp>
NameError: name 'flag' is not defined
我想在exec内部:使用全局变量,传递函数局部变量,能够在本地返回结果并在列表理解测试中使用变量。我还看不到解决方案:您有个主意吗?
答案 0 :(得分:2)
def myfunc():
s = """
users = ['root','service']
flag = True
c_list = [ u for u in users ]
print('list comprehension =',c_list)
c_list_with_test = [ u for u in users if flag ]
print('list comprehension with test =',c_list_with_test)
some_result = 'a result'
"""
nm = {}
exec(s, nm)
print('Result =', nm.get('some_result'))
myfunc()
list comprehension = ['root','service']
使用test = ['root','service']的列表理解
结果=结果
exec
函数仅可用于一个namespace
词典。将nm
变量设置为局部变量的命名空间。
更新:
myglob_var = 'my global var'
def myfunc():
s = """
print('myglob_var =',myglob_var)
users = ['root','service']
flag = True
c_list = [ u for u in users ]
print('list comprehension =',c_list)
c_list_with_test = [ u for u in users if flag ]
print('list comprehension with test =',c_list_with_test)
some_result = 'a result'
"""
nm = {"myglob_var": myglob_var}
exec(s, nm)
print('Result =', nm.get("some_result"))
myfunc()
是否适合在名称空间中定义真正需要的变量?
更新2:
nm = globals().copy()
nm.update(locals())
exec(s, nm)
如何将局部变量传递给名称空间?
答案 1 :(得分:0)
我终于找到了解决方案,但是我发现这真的很丑:
myglob_var = 'my global var'
def myfunc():
flag = True
users = ['root','service']
s = """
print('myglob_var =',myglob_var)
c_list = [ u for u in users ]
print('list comprehension =',c_list)
c_list_with_test = [ u for u in users if flag ]
print('list comprehension with test =',c_list_with_test)
some_result = 'a result'
"""
nm = globals().copy()
nm.update(locals())
exec(s, nm)
print('Result =',nm.get('some_result'))
myfunc()
它给出:
$ python3 test.py
myglob_var = my global var
list comprehension = ['root', 'service']
list comprehension with test = ['root', 'service']
Result = a result
它没有解释为什么当我在exec()中指定locals参数时,它会导致列表理解测试中的唯一变量未定义...