exec()方法的变量在哪里定义?

时间:2018-07-30 16:12:34

标签: python variables exec

当我遇到这个问题时,我试图运行一些将字符串转换为列表的代码。 首先是示例代码:

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的事实,以及我可以单独运行此代码的事实,所以我不知道问题出在哪里。

我尝试在Internet上进行一些搜索,但是由于我缺乏对低级执行的知识,因此无法找到定义我的特定问题的关键字。 感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

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'>

答案 1 :(得分:1)

在CPython中,函数中的局部变量(通常是?)以一种称为“快速局部变量”的优化方式存储在固定大小的数组中。结果,局部变量无法动态添加到函数中。

exec函数将尝试向该函数添加新的局部变量,但由于该固定大小的数组未更改,因此return语句将不会读取该变量。