python – exec()字节码与任意本地?
例如,假设我想执行代码
value += 5 在我自己的命名空间内(所以结果基本上是mydict [‘value’] = 5).有一个函数exec(),但我必须在那里传递一个字符串: exec('value += 5',mydict) 并且将语句作为字符串传递似乎很奇怪(例如,它没有以这种方式着色). def block(): value += 5 ???(block,mydict) ?最后一行的明显候选者是exec(block .__ code__,mydict),但没有运气:它引发了关于值的UnboundLocalError.我相信它基本上执行block(),而不是块内的代码,所以赋值并不容易 – 这是正确的吗? 当然,另一种可能的解决方案是反汇编块.__代码__… 仅供参考,因为this thread我得到了这个问题.此外,这就是为什么有些人(我未定)要求新语法 using mydict: value += 5 注意这不会引发错误,但也不会改变mydict: def block(value = 0): value += 5 block(**mydict) 解决方法
您可以将字节码而不是字符串传递给exec,您只需要为此目的制作正确的字节码:
>>> bytecode = compile('value += 5','<string>','exec') >>> mydict = {'value': 23} >>> exec(bytecode,mydict) >>> mydict['value'] 28 具体来说,……: >>> import dis >>> dis.dis(bytecode) 1 0 LOAD_NAME 0 (value) 3 LOAD_CONST 0 (5) 6 INPLACE_ADD 7 STORE_NAME 0 (value) 10 LOAD_CONST 1 (None) 13 RETURN_VALUE 加载和存储指令必须是_NAME说服,并且这个编译使得它们如此,而…: >>> def f(): value += 5 ... >>> dis.dis(f.func_code) 1 0 LOAD_FAST 0 (value) 3 LOAD_CONST 1 (5) 6 INPLACE_ADD 7 STORE_FAST 0 (value) 10 LOAD_CONST 0 (None) 13 RETURN_VALUE …函数中的代码被优化为使用_FAST版本,而那些不适用于传递给exec的dict.如果你使用_FAST指令以某种方式开始使用字节码,你可以修改它以使用_NAME类型,例如用bytecodehacks或类似的方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |