如何检测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()

相关文章
相关标签/搜索