exec() 在函数内部不工作 python3.x
exec() not working inside function python3.x
我正在尝试 运行 这段代码,但似乎 exec()
没有执行函数内的字符串:
def abc(xyz):
for i in fn_lst:
s = 'temp=' + i + '(xyz)'
exec(s)
print (temp)
abc('avdfbafadnf')
我收到的错误:
NameError Traceback (most recent call last)
<ipython-input-23-099995c31c78> in <module>()
----> 1 abc('avdfbafadnf')
<ipython-input-21-80dc547cb34f> in abc(xyz)
4 s = 'temp=' + i + '(word)'
5 exec(s)
----> 6 print (temp)
NameError: name 'temp' is not defined
fn_lst
是函数名称列表,即:['has_at', 'has_num' ...]
在这种情况下,如果可能的话,请告诉我 exec()
的替代方法。
不要将 exec
与函数名称一起使用,只需将函数对象保留在列表中即可:
fn_lst = [has_at, has_num, ...]
并直接执行调用:
def abc(xyz):
for i in fn_lst:
temp= i(xyz)
print(temp)
首先,我们展示如何通过传递给 exec() 的字符串设置一个变量,该变量在调用 exec() 之外可用。然后我们展示一些示例,说明如何在调用 exec() 的函数调用之外使变量可用。
核心概念包括 exec() 作为参数、要执行的字符串以及用作全局和局部范围的两个字典。
例如,我们可以传递实际的全局和局部作用域,像这样:
exec( 'a = 3', globals(), locals() )
print( a )
这将打印以下结果:
3
但是,我们选择将哪些字典传递给 exec() 具有相当大的灵活性,这提供了几种方法来从调用 exec() 的函数中设置局部范围内的变量。
例如,我们可以将当前局部作用域传递给一个函数,然后将其用作 exec() 的局部字典,如下所示:
def demofunction( adict ):
exec( 'a=1.', globals(), adict )
print( 'before calling the function' )
try:
print( a )
except Exception as e:
print( e )
demofunction( locals() )
print( 'after calling the function' )
print( 'a =', a )
这会打印:
before calling the function
name 'a' is not defined
after calling the function
a = 1.0
由于调用范围对于函数内部的范围是全局的,从函数内部设置局部变量的另一种简单方法是仅使用 globals() 作为 exec() 的第二个参数。
def demofunction( adict ):
exec( 'a=1.', None, globals() )
print( 'before calling the function' )
try:
print( a )
except Exception as e:
print( e )
demofunction( locals() )
print( 'after calling the function' )
print( 'a =', a )
再次打印:
before calling the function
name 'a' is not defined
after calling the function
a = 1.0
因此,我们看到 exec() 实际上可以从函数内部在我们的本地范围内创建变量。
此外,您不限于 globals() 和 locals()。您可以将任何有效的字典传递给它。
def demofunction( adict ):
exec( 'a=1.', None, adict )
somedict = { 'b': 1 }
print( somedict )
demofunction( somedict )
print( somedict )
现在输出是:
{'b': 1}
{'b': 1, 'a': 1.0}
注意:在第一个示例中,单独使用本地参数就足够了,即省略 globals()。两者都包含在这里以说明更一般的情况。您可以在 Python、Python Textbook - Scope
中阅读有关“Scope”的内容
我想提一下,之前在本主题中建议的许多“标准”答案在函数内部不起作用。例如,考虑以下代码片段:
def test():
exec( 'a = 3', globals(), locals() )
print(a)
test()
一切似乎都很好。但是,此代码在 Python 3:
中给出错误
NameError: name 'a' is not defined
我尝试了一些使用其他论坛中建议的 compile
函数的方法,但它们仍然对我不起作用(至少对于我提到的选项)。
根据我的研究,这是我见过的最接近工作的代码:
def test():
lcls = locals()
exec( 'a = 3', globals(), lcls )
a = lcls["a"]
print(f'a is {a}')
test()
成功打印:
a is 3
我认为这是一个总体上很重要的话题。有时,当您使用 Sympy 等符号代数库时,通过 exec
函数定义变量对于科学计算来说非常方便。
我希望有人知道这个问题的好答案。
编辑:
现在我很少用exec
了。我已经意识到 OP 问题的 better/shorter 解决方案是使用 eval
函数简单地定义局部变量。 OP 的代码可以写成:
def abc(xyz):
for i in fn_lst:
temp = eval(i + '(xyz)')
print (temp)
abc('avdfbafadnf')
# problem solved :)
由于变量名 temp
已经硬编码到函数中,使用 eval
不会改变解决方案的通用性。如果事先不知道变量的名称,eval
也可以按如下方式使用:
def advanced_eval(expr):
var_names = expr.split('=')[0].replace(' ','')
rhs_values = eval('='.join(expr.split('=')[1:]))
return var_names, rhs_values
如果定义 name,value = advanced_eval('a=3+3')
,代码将有效地输出 name = 'a'
和 value = 6
。
在这个问题上花了这么多时间进行命中和试验之后,我可以说像这样使用exec在函数内部没有任何问题,否则会抛出错误。
我已经对函数和变量进行了测试。
def main():
x = "def y():\n\treturn('This will work')"
#pass only globals() not locals()
exec(x,globals())
print(y())
main()
def test():
#pass only globals() not locals()
exec( 'a = 3', globals())
print(a)
test()
这是在 W3School's online interpreter 上运行的屏幕截图(您可以 copy/paste 在这里自己测试)
我正在尝试 运行 这段代码,但似乎 exec()
没有执行函数内的字符串:
def abc(xyz):
for i in fn_lst:
s = 'temp=' + i + '(xyz)'
exec(s)
print (temp)
abc('avdfbafadnf')
我收到的错误:
NameError Traceback (most recent call last)
<ipython-input-23-099995c31c78> in <module>()
----> 1 abc('avdfbafadnf')
<ipython-input-21-80dc547cb34f> in abc(xyz)
4 s = 'temp=' + i + '(word)'
5 exec(s)
----> 6 print (temp)
NameError: name 'temp' is not defined
fn_lst
是函数名称列表,即:['has_at', 'has_num' ...]
在这种情况下,如果可能的话,请告诉我 exec()
的替代方法。
不要将 exec
与函数名称一起使用,只需将函数对象保留在列表中即可:
fn_lst = [has_at, has_num, ...]
并直接执行调用:
def abc(xyz):
for i in fn_lst:
temp= i(xyz)
print(temp)
首先,我们展示如何通过传递给 exec() 的字符串设置一个变量,该变量在调用 exec() 之外可用。然后我们展示一些示例,说明如何在调用 exec() 的函数调用之外使变量可用。
核心概念包括 exec() 作为参数、要执行的字符串以及用作全局和局部范围的两个字典。
例如,我们可以传递实际的全局和局部作用域,像这样:
exec( 'a = 3', globals(), locals() )
print( a )
这将打印以下结果:
3
但是,我们选择将哪些字典传递给 exec() 具有相当大的灵活性,这提供了几种方法来从调用 exec() 的函数中设置局部范围内的变量。
例如,我们可以将当前局部作用域传递给一个函数,然后将其用作 exec() 的局部字典,如下所示:
def demofunction( adict ):
exec( 'a=1.', globals(), adict )
print( 'before calling the function' )
try:
print( a )
except Exception as e:
print( e )
demofunction( locals() )
print( 'after calling the function' )
print( 'a =', a )
这会打印:
before calling the function
name 'a' is not defined
after calling the function
a = 1.0
由于调用范围对于函数内部的范围是全局的,从函数内部设置局部变量的另一种简单方法是仅使用 globals() 作为 exec() 的第二个参数。
def demofunction( adict ):
exec( 'a=1.', None, globals() )
print( 'before calling the function' )
try:
print( a )
except Exception as e:
print( e )
demofunction( locals() )
print( 'after calling the function' )
print( 'a =', a )
再次打印:
before calling the function
name 'a' is not defined
after calling the function
a = 1.0
因此,我们看到 exec() 实际上可以从函数内部在我们的本地范围内创建变量。
此外,您不限于 globals() 和 locals()。您可以将任何有效的字典传递给它。
def demofunction( adict ):
exec( 'a=1.', None, adict )
somedict = { 'b': 1 }
print( somedict )
demofunction( somedict )
print( somedict )
现在输出是:
{'b': 1}
{'b': 1, 'a': 1.0}
注意:在第一个示例中,单独使用本地参数就足够了,即省略 globals()。两者都包含在这里以说明更一般的情况。您可以在 Python、Python Textbook - Scope
中阅读有关“Scope”的内容我想提一下,之前在本主题中建议的许多“标准”答案在函数内部不起作用。例如,考虑以下代码片段:
def test():
exec( 'a = 3', globals(), locals() )
print(a)
test()
一切似乎都很好。但是,此代码在 Python 3:
中给出错误NameError: name 'a' is not defined
我尝试了一些使用其他论坛中建议的 compile
函数的方法,但它们仍然对我不起作用(至少对于我提到的选项)。
根据我的研究,这是我见过的最接近工作的代码:
def test():
lcls = locals()
exec( 'a = 3', globals(), lcls )
a = lcls["a"]
print(f'a is {a}')
test()
成功打印:
a is 3
我认为这是一个总体上很重要的话题。有时,当您使用 Sympy 等符号代数库时,通过 exec
函数定义变量对于科学计算来说非常方便。
我希望有人知道这个问题的好答案。
编辑:
现在我很少用exec
了。我已经意识到 OP 问题的 better/shorter 解决方案是使用 eval
函数简单地定义局部变量。 OP 的代码可以写成:
def abc(xyz):
for i in fn_lst:
temp = eval(i + '(xyz)')
print (temp)
abc('avdfbafadnf')
# problem solved :)
由于变量名 temp
已经硬编码到函数中,使用 eval
不会改变解决方案的通用性。如果事先不知道变量的名称,eval
也可以按如下方式使用:
def advanced_eval(expr):
var_names = expr.split('=')[0].replace(' ','')
rhs_values = eval('='.join(expr.split('=')[1:]))
return var_names, rhs_values
如果定义 name,value = advanced_eval('a=3+3')
,代码将有效地输出 name = 'a'
和 value = 6
。
在这个问题上花了这么多时间进行命中和试验之后,我可以说像这样使用exec在函数内部没有任何问题,否则会抛出错误。 我已经对函数和变量进行了测试。
def main():
x = "def y():\n\treturn('This will work')"
#pass only globals() not locals()
exec(x,globals())
print(y())
main()
def test():
#pass only globals() not locals()
exec( 'a = 3', globals())
print(a)
test()
这是在 W3School's online interpreter 上运行的屏幕截图(您可以 copy/paste 在这里自己测试)