【发布时间】:2023-03-05 10:33:01
【问题描述】:
首先,请注意,它不像其他关于 exec 内部变量的 SO 问题。这是一个在 exec 中的列表理解 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()
这一次,它再次触发了同样的问题:users 被定义但不是 flag 在 exec 中:
$ 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 内部:使用全局变量,传递函数局部变量,能够在本地返回结果并在列表理解测试中使用变量。我还看不到解决方案:您有什么想法吗?
【问题讨论】:
-
这是对您问题的回答 - stackoverflow.com/a/39647647/2172752 只需将
exec称为exec(s, globals()) -
它对我有用!
-
@MartenCatcher 是的,不,不要那样做。 OP 已经表示他们不希望在全局范围内定义这些变量。它们应该是局部变量。
-
@Aran-Fey 是的,好的。我用
local namespace声明示例回复了帖子。
标签: python python-3.x