<p><code>ldict = {}</code>技巧创建一个替代的本地命名空间,以便在<code>exec</code>内使用。这很有用,因为<code>locals()</code>返回的dict不像python2中那样直接写入实际的局部变量。在</p>
<p>但是替代名称空间<code>{}</code>是空的。它不包含您的<code>locals()</code>,因此它没有<code>val</code>。尝试使用<code>ldict = {**locals()}</code>来将局部变量的内容复制到替换的局部变量<code>ldict</code>。在</p>
<hr/>
<p>请记住,您必须从ldict读取exec创建的所有“local”。因此,<code>print(tg)</code>也不起作用,因为它只在一个替代的本地命名空间中被分配。你可能不想每个循环都做一个新的。只要<code>.update()</code>一个你事先做的。在</p>
<pre><code>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'])
</code></pre>
<hr/>
<p>为了优化性能,Python3中的编译器必须事先知道局部变量的数量和名称。(这不适用于<code>globals()</code>,它们仍在写入。)</p>
<p>如果你事先知道他们,你可以从他们那里分配,例如</p>
^{pr2}$
<p>如果你需要不止一本,你可以把一本字典解压成本地人,比如</p>
<pre><code>a, b, c = (ldict[key] for key in ['a', 'b', 'c'])
</code></pre>
<p>或者您可以将整个dict转储到一个简单的命名空间中,并使用<code>.</code>而不是{<cd13>}来访问它们。在</p>
<pre><code>from types import SimpleNamespace
# ...
ns = SimpleNamespace(**ldict)
print(ns.tg)
</code></pre>
<p>您也可以<code>exec</code>任何需要新局部变量的代码,因为您可以给<code>exec</code>一个<code>ldict</code>名称空间。在</p>
<pre><code>exec("print(tg)", globals(), ldcit)
</code></pre>
<hr/>
<p>我知道您的示例代码可能会比原始代码简化,但它似乎根本不需要<code>exec</code>。除非您绝对需要,否则通常认为使用<code>exec</code>是一种不好的形式,因为它混淆了静态分析工具,并且在运行时编译字符串的速度很慢,尤其是在这样的循环中重复时。在</p>
<p>如果必须使用exec,那么最好将循环放在exec字符串中(使用三个引号),而不是将exec调用放在循环中。这样,字符串只需编译一次,而不必为每个循环编译一次。在</p>