2017-10-10 77 views
0

我探索__code__属性和ast模块,发现异常行为,该函数的第一个电话不输出任何东西:如何修补函数的__code__?

In [3]: def foo(): 
    ...:  print('foo') 
    ...: 
In [4]: p = ast.parse("".join(inspect.getsourcelines(foo)[0])) 
In [5]: p.body[0].body = ast.parse("print('bar')").body 
In [6]: foo.__code__ = compile(p, foo.__code__.co_filename, 'exec') 
In [7]: foo() # Nothing happens?? 

In [8]: foo() # Okay, let's try again 
bar 

这到底是怎么回事?

回答

2

您可能认为您已将foo.__code__设置为打印bar的代码对象,但这不是您所做的。您已将foo.__code__设置为代码对象,定义了一个新的foo函数,该函数打印bar。这有点像

def foo(): 
    global foo 
    def foo(): 
     print('bar') 

第一次运行之后,foo是新扎打印功能,并运行新的功能打印bar

+0

谢谢!因此,正确的方法是将第6行更改为'foo .__ code__ = compile(ast.Module(p.body [0] .body),foo .__ code __。co_filename,'e​​xec')'。 – ElectricHedgehog

+1

@ElectricHedgehog:可能吗?我还没有尝试过,而且我不知道你是否可能会遇到AST错误,或者遇到了一些奇怪的边缘情况或不兼容问题。 – user2357112