如何檢測Python變量是否爲函數?

我有一個變量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'>

#1樓

若是要檢測語法上看起來像函數的全部事物:函數,方法,內置fun / meth,lambda ...但排除可調用對象(定義了__call__方法的對象),請嘗試如下方法: 測試

import types
isinstance(x, (types.FunctionType, types.BuiltinFunctionType, types.MethodType, types.BuiltinMethodType, types.UnboundMethodType))

我將其與inspect模塊中的is*()檢查代碼進行了比較,上面的表達式更加完整,特別是若是您的目標是過濾掉任何功能或檢測對象的常規屬性時。 ui


#2樓

在先前的答覆以後,我想到了這一點: 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)

#3樓

不管函數是一個類,所以您均可以使用實例x的類的名稱並進行比較: code

if(x.__class__.__name__ == 'function'):
     print "it's a function"

#4樓

您能夠檢查用戶定義的函數是否具備func_namefunc_doc等屬性,而不是檢查'__call__' (這不是函數所獨有的),這對於方法來講無效。 對象

>>> def x(): pass
... 
>>> hasattr(x, 'func_name')
True

另外一種檢查方法是使用inspect模塊中的isfunction()方法。 get

>>> import inspect
>>> inspect.isfunction(x)
True

要檢查對象是否爲方法,請使用inspect.ismethod()


#5樓

公認的答案是在提供該答案時被認爲是正確的。 事實證實, 沒有可替代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()

相關文章
相關標籤/搜索