我有一個變量x
,我想知道它是否指向一個函數。 緩存
我曾但願我能夠作些相似的事情: app
>>> isinstance(x, function)
但這給了我: ide
Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name 'function' is not defined
我之因此選擇,是由於 函數
>>> type(x) <type 'function'>
若是要檢測語法上看起來像函數的全部事物:函數,方法,內置fun / meth,lambda ...但排除可調用對象(定義了__call__
方法的對象),請嘗試如下方法: 測試
import types isinstance(x, (types.FunctionType, types.BuiltinFunctionType, types.MethodType, types.BuiltinMethodType, types.UnboundMethodType))
我將其與inspect
模塊中的is*()
檢查代碼進行了比較,上面的表達式更加完整,特別是若是您的目標是過濾掉任何功能或檢測對象的常規屬性時。 ui
在先前的答覆以後,我想到了這一點: spa
from pprint import pprint def print_callables_of(obj): li = [] for name in dir(obj): attr = getattr(obj, name) if hasattr(attr, '__call__'): li.append(name) pprint(li)
不管函數是一個類,所以您均可以使用實例x的類的名稱並進行比較: code
if(x.__class__.__name__ == 'function'): print "it's a function"
您能夠檢查用戶定義的函數是否具備func_name
, func_doc
等屬性,而不是檢查'__call__'
(這不是函數所獨有的),這對於方法來講無效。 對象
>>> def x(): pass ... >>> hasattr(x, 'func_name') True
另外一種檢查方法是使用inspect
模塊中的isfunction()
方法。 get
>>> import inspect >>> inspect.isfunction(x) True
要檢查對象是否爲方法,請使用inspect.ismethod()
公認的答案是在提供該答案時被認爲是正確的。 事實證實, 沒有可替代的callable()
,它能夠在Python 3.2中返回:具體來講, callable()
檢查要測試的對象的tp_call
字段。 沒有普通的Python等效項。 大多數建議的測試在大多數狀況下都是正確的:
>>> class Spam(object): ... def __call__(self): ... return 'OK' >>> can_o_spam = Spam() >>> can_o_spam() 'OK' >>> callable(can_o_spam) True >>> hasattr(can_o_spam, '__call__') True >>> import collections >>> isinstance(can_o_spam, collections.Callable) True
咱們能夠經過從類中刪除__call__
來給猴子__call__
。 爲了使事情變得更加使人興奮,請在實例中添加一個僞造的__call__
!
>>> del Spam.__call__ >>> can_o_spam.__call__ = lambda *args: 'OK?'
注意,這確實是不可調用的:
>>> can_o_spam() Traceback (most recent call last): ... TypeError: 'Spam' object is not callable
callable()
返回正確的結果:
>>> callable(can_o_spam) False
可是hasattr
是錯誤的 :
>>> hasattr(can_o_spam, '__call__') True
can_o_spam
具備該屬性; 只是在調用實例時不使用它。
更微妙的是, isinstance()
也會出錯:
>>> isinstance(can_o_spam, collections.Callable) True
由於咱們以前使用了此檢查,後來又刪除了該方法, abc.ABCMeta
緩存結果。 能夠說這是abc.ABCMeta
的錯誤。 就是說,與使用callable()
自己相比,實際上沒有任何方法能夠產生比結果更準確的結果,由於沒法以其餘任何方式訪問typeobject->tp_call
slot方法。
只需使用callable()