如何检测一个pythonvariables是否是一个函数?

我有一个variables, x ,我想知道它是否指向一个函数。

我本来希望能做到这样的事情:

 >>> isinstance(x, function) 

但是那给了我:

 Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name 'function' is not defined 

我select的原因是因为

 >>> type(x) <type 'function'> 

如果是Python 2.x或Python 3.2+,那么也可以使用callable() 。 它曾经被弃用,但现在不赞成,所以你可以再次使用它。 你可以阅读这里的讨论: http : //bugs.python.org/issue10518 。 你可以这样做:

 callable(obj) 

如果这是针对Python 3.x,但在3.2之前,请检查该对象是否具有__call__属性。 你可以这样做:

 hasattr(obj, '__call__') 

经常提出的types.FunctionTypes方法是不正确的,因为它不能涵盖许多你可能希望它通过的情况,就像内置函数一样:

 >>> isinstance(open, types.FunctionType) False >>> callable(open) True 

检查鸭型物品的正确方法是询问他们是否嘎嘎,而不是看他们是否适合装鸭子的容器。 不要使用types.FunctionType除非你对函数是什么有一个非常具体的概念。

内build命名空间中没有构造函数的内buildtypes(如函数,生成器,方法)位于types模块中。 您可以在isinstance调用中使用types.FunctionType

 In [1]: import types In [2]: types.FunctionType Out[2]: <type 'function'> In [3]: def f(): pass ...: In [4]: isinstance(f, types.FunctionType) Out[4]: True In [5]: isinstance(lambda x : None, types.FunctionType) Out[5]: True 

从Python 2.1开始,您可以从inspect模块导入isfunction

 >>> from inspect import isfunction >>> def f(): pass >>> isfunction(f) True >>> isfunction(lambda x: x) True 

被接受的答案在当时被认为是正确的; 事实certificate,在python 3.2中没有可替代callable() :具体来说, callable()检查被testing对象的tp_call字段。 没有普通的python等价物。 大部分build议的testing大部分时间都是正确的:

 >>> 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__实例!

 >>> 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.ABCMetacaching结果。 可以说这是abc.ABCMeta一个bug。 也就是说,除了使用callable()本身之外,真的没有办法产生比结果更精确的结果,因为typeobject->tp_call slot方法不能以任何其他方式访问。

只需使用callable()

以下应该返回一个布尔值:

 callable(x) 

Python的2to3工具( http://docs.python.org/dev/library/2to3.html )build议:

 import collections isinstance(obj, collections.Callable) 

看起来这是因为http://bugs.python.org/issue7006而不是;hasattr(x, '__call__')方法。

如果传入的对象可以在Python中callable(x) 返回true,但该函数在Python 3.0中不存在,正确地说,不会区分:

 class A(object): def __call__(self): return 'Foo' def B(): return 'Bar' a = A() b = B print type(a), callable(a) print type(b), callable(b) 

你会得到<class 'A'> True<type function> True作为输出。

isinstance很好地工作,以确定是否是一个函数(尝试isinstance(b, types.FunctionType) ); 如果你真的有兴趣知道是否可以调用某个东西,你可以使用hasattr(b, '__call__')或者只是尝试一下。

 test_as_func = True try: b() except TypeError: test_as_func = False except: pass 

这当然不会告诉你它是否可调用,但在执行时抛出一个TypeError ,或者一开始就不可调用。 这对你来说可能没有关系。

如果要检测语法上看起来像函数的所有内容:函数,方法,内置fun / meth,lambda …但排除可调用对象(定义了__call__方法的对象),请尝试下面的方法:

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

我将它与inspect模块中的is*()检查代码进行了比较,上面的expression式更加完整,特别是如果您的目标是筛选出任何函数或检测到对象的常规属性。

尝试使用callable(x)

由于类也有__call__方法,我build议另一种解决scheme:

 class A(object): def __init__(self): pass def __call__(self): print 'I am a Class' MyClass = A() def foo(): pass print hasattr(foo.__class__, 'func_name') # Returns True print hasattr(A.__class__, 'func_name') # Returns False as expected print hasattr(foo, '__call__') # Returns True print hasattr(A, '__call__') # (!) Returns True while it is not a function 

函数只是一个带__call__方法的类,所以你可以做

 hasattr(obj, '__call__') 

例如:

 >>> hasattr(x, '__call__') True >>> x = 2 >>> hasattr(x, '__call__') False 

这是做到这一点的“最佳”方法,但是根据你为什么需要知道它是否可调用或注意,你可以把它放在try / execpt块中:

 try: x() except TypeError: print "was not callable" 

这是有争议的,如果尝试/除了更Python'y比做if hasattr(x, '__call__'): x() __call__ if hasattr(x, '__call__'): x() ..我会说hasattr是更准确的,因为你不会意外地捕捉到错误的TypeError,例如:

 >>> def x(): ... raise TypeError ... >>> hasattr(x, '__call__') True # Correct >>> try: ... x() ... except TypeError: ... print "x was not callable" ... x was not callable # Wrong! 

您可以检查用户定义的函数是否具有func_namefunc_doc等属性,而不是检查'__call__' (这不是函数的专有函数)。这对于方法不起作用。

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

另一种检查方式是使用inspect模块中的isfunction()方法。

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

要检查对象是否是方法,请使用inspect.ismethod()

以下是其他几种方法:

 def isFunction1(f) : return type(f) == type(lambda x: x); def isFunction2(f) : return 'function' in str(type(f)); 

下面是我想到第二个:

 >>> type(lambda x: x); <type 'function'> >>> str(type(lambda x: x)); "<type 'function'>" # Look Maa, function! ... I ACTUALLY told my mom about this! 

请注意,Python类也是可调用的。

要获得函数(和函数,我们指的是标准函数和lambda)使用:

 import types def is_func(obj): return isinstance(obj, (types.FunctionType, types.LambdaType)) def f(x): return x assert is_func(f) assert is_func(lambda x: x) 

无论函数是什么类,所以你可以采取实例x的类的名称和比较:

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

在某些答案中提到的使用hasattr(obj, '__call__')callable(.)的解决scheme有一个主要缺点:它们都使用__call__()方法返回类和实例类的True 。 例如。

 >>> import collections >>> Test = collections.namedtuple('Test', []) >>> callable(Test) True >>> hasattr(Test, '__call__') True 

检查一个对象是否是一个用户定义的函数(而不是一个)的一个正确方法是使用isfunction(.)

 >>> import inspect >>> inspect.isfunction(Test) False >>> def t(): pass >>> inspect.isfunction(t) True 

如果你需要检查其他types,看看检查 – 检查活物 。

在Python3中,我想出了type (f) == type (lambda x:x) ,如果f是一个函数,则返回True否则返回False 。 但我认为我更喜欢isinstance (f, types.FunctionType) ,这感觉不太专门。 我想做type (f) is function ,但是这不起作用。

之前的回复之后,我想出了这个:

 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) 

如果代码将继续执行调用,如果值是可调用的,只需执行调用并捕获TypeError

 def myfunc(x): try: x() except TypeError: raise Exception("Not callable")