Nev*_*vir 4 python python-2.7 python-exec
好的,所以我在一个工具的配置脚本是exec'python脚本' 的环境中工作.exec调用是这样的:
outer.py:
exec(open("inner.py").read(), globals(), {})
Run Code Online (Sandbox Code Playgroud)
现在,我想在exec'd脚本中做一些相对基本的迭代.在这种情况下,当某些值不在白名单中时执行工作:
inner.py:
items = (
'foo/bar',
'foo/baz',
'foof',
'barf/fizz',
)
whitelist = (
'foo/',
)
for key in items:
try:
# Not terribly efficient, but who cares; computers are fast.
next(True for prefix in whitelist if key.startswith(prefix))
# Do some work here when the item doesn't match the whitelist.
except StopIteration:
print("%10s isn't in the whitelist!" % key)
Run Code Online (Sandbox Code Playgroud)
运行python inner.py产生预期结果:
foof isn't in the whitelist!
barf/fizz isn't in the whitelist!
Run Code Online (Sandbox Code Playgroud)
这是一个奇怪的部分:运行python outer.py似乎表明解释器对生成器的范围感到困惑:
Traceback (most recent call last):
File "outer.py", line 1, in <module>
exec(open("inner.py").read(), globals(), {})
File "<string>", line 15, in <module>
File "<string>", line 15, in <genexpr>
NameError: global name 'key' is not defined
Run Code Online (Sandbox Code Playgroud)
其他一些说明:
您可以print(key)在for循环内部(在生成器运行之前)完成.
locals()在解决问题的exec行中替换空字典outer.py,但该代码不受我的控制.
我正在运行OS X内置的Python 2.7.2(Mountain Lion).
确实很狡猾.
来自doc:
如果给出两个单独的对象作为全局变量和局部变量,则代码将被执行,就像它嵌入在类定义中一样.
(请注意,当您exec(..., globals(), locals())在模块级别运行时,这不适用,因为globals() is locals(),即不是两个单独的对象).
这表明您可以通过运行此脚本来简单地重现该问题:
class A(object):
items = (
'foo/bar',
'foo/baz',
'foof',
'barf/fizz',
)
whitelist = (
'foo/',
)
for key in items:
try:
# Not terribly efficient, but who cares; computers are fast.
next(True for prefix in whitelist if key.startswith(prefix))
# Found!
print(key)
except StopIteration:
pass
Run Code Online (Sandbox Code Playgroud)
"好的,但为什么我在这里得到错误?"
很高兴你问.答案就在这里.