exec() 方法的变量在哪里定义?
Where are exec() method's variables defined?
当我遇到这个问题时,我正在尝试 运行 一些将字符串转换为列表的代码。
首先这里是一个示例代码:
def str_to_list(s):
s = s.replace('\n', '')
exec('res="{}"'.format(str(s)))
print(res)
s = '[0. 1. 0. 0.\n 0. 2. 5.]'
l = str_to_list(s)
当我 运行 这个时,我得到一个关于 res
的 NameError,起初我认为它可以是一种局部变量到 exec() 方法中,但后来我意识到我可以 运行 这个代码:
s = '[0. 1. 0. 0.\n 0. 2. 5.]'
s = s.replace('\n', '')
exec('res="{}"'.format(str(s)))
print(res)
因为我没有尝试从函数外部调用 res
,而且我可以单独 运行 这段代码,所以我无法弄清楚问题。
我尝试在互联网上进行一些搜索,但由于我缺乏底层执行知识,我无法找到定义我的特定问题的关键字。
感谢您的帮助。
在 CPython 中,函数中的局部变量(通常?)存储在固定大小的数组中,优化称为 "fast locals"。因此,无法将局部变量动态添加到函数中。
exec 函数将尝试将新的局部变量添加到函数中,但它不会被 return 语句读取,因为固定大小的数组没有更改。
如 the exec
docs 中所述,您需要给 exec
一个合适的 locals
字典。例如,
def str_to_list(s):
s = s.replace('\n', '')
d = {}
exec('res="{}"'.format(s), None, d)
return d['res']
s = '[0. 1. 0. 0.\n 0. 2. 5.]'
print(str_to_list(s))
输出
[0. 1. 0. 0. 0. 2. 5.]
但是,通常建议您避免使用 exec
,除非您 确实 需要它。有关详细信息,请参阅 Ned Batchelder 的 Eval really is dangerous。那里的信息也适用于 exec
.
如果您只想从字符串创建列表,您可以使用 ast.literal_eval
。例如,
from ast import literal_eval
s = '[0, 1, 0, 0, 0, 2, 5]'
seq = literal_eval(s)
print(seq, type(seq))
输出
[0, 1, 0, 0, 0, 2, 5] <class 'list'>
当我遇到这个问题时,我正在尝试 运行 一些将字符串转换为列表的代码。 首先这里是一个示例代码:
def str_to_list(s):
s = s.replace('\n', '')
exec('res="{}"'.format(str(s)))
print(res)
s = '[0. 1. 0. 0.\n 0. 2. 5.]'
l = str_to_list(s)
当我 运行 这个时,我得到一个关于 res
的 NameError,起初我认为它可以是一种局部变量到 exec() 方法中,但后来我意识到我可以 运行 这个代码:
s = '[0. 1. 0. 0.\n 0. 2. 5.]'
s = s.replace('\n', '')
exec('res="{}"'.format(str(s)))
print(res)
因为我没有尝试从函数外部调用 res
,而且我可以单独 运行 这段代码,所以我无法弄清楚问题。
我尝试在互联网上进行一些搜索,但由于我缺乏底层执行知识,我无法找到定义我的特定问题的关键字。 感谢您的帮助。
在 CPython 中,函数中的局部变量(通常?)存储在固定大小的数组中,优化称为 "fast locals"。因此,无法将局部变量动态添加到函数中。
exec 函数将尝试将新的局部变量添加到函数中,但它不会被 return 语句读取,因为固定大小的数组没有更改。
如 the exec
docs 中所述,您需要给 exec
一个合适的 locals
字典。例如,
def str_to_list(s):
s = s.replace('\n', '')
d = {}
exec('res="{}"'.format(s), None, d)
return d['res']
s = '[0. 1. 0. 0.\n 0. 2. 5.]'
print(str_to_list(s))
输出
[0. 1. 0. 0. 0. 2. 5.]
但是,通常建议您避免使用 exec
,除非您 确实 需要它。有关详细信息,请参阅 Ned Batchelder 的 Eval really is dangerous。那里的信息也适用于 exec
.
如果您只想从字符串创建列表,您可以使用 ast.literal_eval
。例如,
from ast import literal_eval
s = '[0, 1, 0, 0, 0, 2, 5]'
seq = literal_eval(s)
print(seq, type(seq))
输出
[0, 1, 0, 0, 0, 2, 5] <class 'list'>