在Python3中如何使用exec根据字典给变量赋值?

2024-04-28 01:22:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我想将list赋给变量,而list和{}都存储在字典measurements中。这是measurements的Python 2版本,变量较少:

measurements = {'tg': [8.184e+16, 8.345e+16, 8.045e+16, 8.520e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]}

def f():
    for key,val in measurements.items():
        exec(key + ' = val') in globals(),locals()
    print (tg)
f()

但是,正如another question中提到的,它不适合Python3。 如果我这样写代码:

^{pr2}$

我得到了这个错误:NameError: name 'val' is not defined


Tags: keyin版本for字典defitemsval
2条回答

ldict = {}技巧创建一个替代的本地命名空间,以便在exec内使用。这很有用,因为locals()返回的dict不像python2中那样直接写入实际的局部变量。在

但是替代名称空间{}是空的。它不包含您的locals(),因此它没有val。尝试使用ldict = {**locals()}来将局部变量的内容复制到替换的局部变量ldict。在


请记住,您必须从ldict读取exec创建的所有“local”。因此,print(tg)也不起作用,因为它只在一个替代的本地命名空间中被分配。你可能不想每个循环都做一个新的。只要.update()一个你事先做的。在

def f():
    ldict = {}
    for key,val in measurements.items():
        ldict.update(locals())
        exec(key + ' = val', globals(),ldict)
        key = ldict[key]
        # exec(key + ' = val') in globals(),locals()
    print (ldict['tg'])

为了优化性能,Python3中的编译器必须事先知道局部变量的数量和名称。(这不适用于globals(),它们仍在写入。)

如果你事先知道他们,你可以从他们那里分配,例如

^{pr2}$

如果你需要不止一本,你可以把一本字典解压成本地人,比如

a, b, c = (ldict[key] for key in ['a', 'b', 'c'])

或者您可以将整个dict转储到一个简单的命名空间中,并使用.而不是{}来访问它们。在

from types import SimpleNamespace

# ...

ns = SimpleNamespace(**ldict)
print(ns.tg)

您也可以exec任何需要新局部变量的代码,因为您可以给exec一个ldict名称空间。在

exec("print(tg)", globals(), ldcit)

我知道您的示例代码可能会比原始代码简化,但它似乎根本不需要exec。除非您绝对需要,否则通常认为使用exec是一种不好的形式,因为它混淆了静态分析工具,并且在运行时编译字符串的速度很慢,尤其是在这样的循环中重复时。在

如果必须使用exec,那么最好将循环放在exec字符串中(使用三个引号),而不是将exec调用放在循环中。这样,字符串只需编译一次,而不必为每个循环编译一次。在

measurements = {'tg': [8.184e+16, 8.345e+16, 8.045e+16, 8.520e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]}

def f():
    for key,val in measurements.items():
        exec('{} = {}'.format(key, val))
    print (tg)

    local = locals()
    for key in measurements.keys():
        print 'Key: ', key, ', Value: ', local[key]
f()

Python3:

^{pr2}$

输出:

[8.184e+16, 8.345e+16, 8.045e+16, 8.52e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]
Key:  tg , Value:  [8.184e+16, 8.345e+16, 8.045e+16, 8.52e+16, 8.322e+16, 7.622e+16, 4.305e+16, 2.203e+16]

相关问题 更多 >