2017-10-10 105 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