2012-10-08 40 views
11

Python函數具有一個代碼對象__code__ Python函數。獲得一個代碼對象

A sys.settrace跟蹤frame有一個f_code代碼對象。

對於那些調用是功能示蹤劑,我怎麼能得到函數對象(及其__annotation__成員)?

到目前爲止,通過試驗和錯誤,我有:

if hasattr(frame.f_globals.get(frame.f_code.co_name),"__annotations__"): 

這似乎爲職能的工作,但不能用於類的成員函數;更糟糕的是,它將類成員函數與同名的頂級函數混淆了。

(我關於Python 3.2.3(Xubuntu上)我看到了Python 3.3 inspect模塊具有signature功能;將在返回註釋的代碼對象或者它太需要一個函數對象?)

回答

5

通過inspect.getframeinfo模塊。 我的意思是 - 有這樣做在Python沒有直接的方式 - 大多數時候,你可以得到代碼對象的保持,而無需已經具有的功能,它是通過框架instrospection。

檢查的getframeinfo函數不返回有關框架正在運行的一些信息,那麼你可以通過獲取其名稱檢索功能對象。

艱難這取決於具體的實現有一些缺點:

>>> import inspect 
>>> def a(): 
... return inspect.currentframe() 
... 

>>> inspect.getframeinfo(a()) 
Traceback(filename='<stdin>', lineno=2, function='a', code_context=None, index=None) 
>>> b = inspect.getframeinfo(a()) 
>>> b.function 
'a' 

的另一種方式,但仍實現相關的,是用GC模塊(垃圾收集器),以獲得引薦表示編碼對象。

>>> import gc 
>>> from types import FunctionType 
>>> def a(): pass 
... 
>>> code = a.__code__ 

>>> [obj for obj in gc.get_referrers(code) if isinstance(obj, FunctionType) ][0] 
<function a at 0x7f1ef4484500> 
>>> 

- 這就是Python 3 - 爲Python 2應該由func_code

+0

了'inspect.getframeinfo'元組的'function'字段替換__code__似乎是一個字符串,而不是一個函數對象。 gc方法冒着多重推薦人的風險? – Will

+0

我已經結束了使用gc.get_referrers(...)[0] – Will

+1

您可以添加一個檢查,看是否func_code/__ code__是你想要的清單comprehension.This代碼對象仍然失敗,如果你生成具有多種功能與相同的代碼對象有不同的關閉,例如與裝飾者。我想,人們可以對func_closure每個... –