注意:这个问题假设 Python 2.7.3。
我正在寻找一种合理的方法来动态修改函数的本地命名空间,最好以一种给函数体函数添加最少混乱的方式。
我的想法是这样的:
import os
from namespace_updater import update_locals
def somefunc(x, y, z):
# ...
# ...
# this and that
# ...
# ...
if os.environ.get('FROBNICATE'):
from frobnitz import frobnicate
update_locals(frobnicate(locals()))
#
# life goes on, possibly with duly frobnicated local variables...
# ...
# ...
# ...
Thanks!
PS:以下是行不通的方法。
最幼稚的方法是这样的:
locals().update(new_locals(locals())
...但是的文档locals()非常明确地警告不要依赖此类巫毒来修改局部变量,因此请不要将其作为答案提交(除非您可以提出一个很好的案例来忽略文档的警告)。
接下来的天真的规模是这样的
for k, v in new_locals(locals()).items():
exec ('%s = v' % k)
AFAICT,这样的代码不能“不碍事”(即,它has位于函数体内),这并不理想。但真正的破坏因素是exec ('%s = v' % k)
hack 可能会导致一些奇怪的错误。
当我写“奇怪的错误”时,我的意思是“对于那些缺乏掌握的人来说看起来很奇怪的错误”exec ('%s = v' % k)
正如我的”。我对这个黑客的掌握有多薄弱?要回答这个问题,请考虑下面的脚本。它有三个变体:(1) 完全如图所示;(2) 删除前导后#
18号线; (3) 删除第一个后#
在第 15 行和第 18 行中(即对于此变体,没有注释掉任何代码)。我无法预测该脚本的变体 (2) 和 (3) 的行为。我什至无法以超过 50% 的置信度预测变体 (1) 的行为。这就是我的把握是多么脆弱exec ('%s = v' % k)
黑客。除非您能够自信且正确地预测该脚本的三个变体将如何运行(在 python 2.7 下),否则可以肯定地说,您对情况的掌握和我的一样脆弱,您可能应该远离exec ('%s = v' % k)
too.
x = 'global x' # 01
y = 'global y' # 02
def main(): # 03
x = 'local x' # 04
y = 'local y' # 05
run(locals()) # 06
print 'OK' # 07
return 0 # 08
# 09
def run(namespace): # 10
global y # 11
print locals().keys() # 12
for k, v in namespace.items(): # 13
print '%s <- %r' % (k, v) # 14
exec ('%s = v' % k) #in locals() # 15
print locals().keys() # 16
x = x # 17
#z = lambda: k # 18
print x # 19
print y # 20
# 21
exit(main()) # 22