如何检测Python变量是否为函数?

时间:2022-05-27 07:20:07

I have a variable, x, and I want to know whether it is pointing to a function or not.

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

I had hoped I could do something like:

我曾希望我能做点什么:

>>> isinstance(x, function)

But that gives me:

但这给了我:

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

The reason I picked that is because

我选这个是因为。

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

21 个解决方案

#1


608  

If this is for Python 2.x or for Python 3.2+, you can also use callable(). It used to be deprecated, but is now undeprecated, so you can use it again. You can read the discussion here: http://bugs.python.org/issue10518. You can do this with:

如果这是用于Python 2的。对于Python 3.2+,您也可以使用callable()。它曾经被弃用,但现在不被弃用,所以您可以再次使用它。您可以在这里阅读本文的讨论:http://bugs.python.org/e10518。你可以这样做:

callable(obj)

If this is for Python 3.x but before 3.2, check if the object has a __call__ attribute. You can do this with:

如果这是用于python3的。但在3.2之前,检查对象是否具有__call__属性。你可以这样做:

hasattr(obj, '__call__')

The oft-suggested types.FunctionTypes approach is not correct because it fails to cover many cases that you would presumably want it to pass, like with builtins:

oft-suggested类型。函数类型的方法是不正确的,因为它不能覆盖许多您可能希望它通过的情况,比如内置函数:

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

>>> callable(open)
True

The proper way to check properties of duck-typed objects is to ask them if they quack, not to see if they fit in a duck-sized container. Don't use types.FunctionType unless you have a very specific idea of what a function is.

检查鸭子类型对象属性的正确方法是询问它们是否嘎嘎,而不是看它们是否适合于一个鸭子大小的容器。不要使用类型。除非你对函数是什么有一个非常明确的概念。

#2


226  

Builtin types that don't have constructors in the built-in namespace (e.g. functions, generators, methods) are in the types module. You can use types.FunctionType in an isinstance call.

内置名称空间中没有构造函数的构建类型(例如函数、生成器、方法)在类型模块中。您可以使用类型。一个isinstance调用中的函数类型。

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

#3


77  

Since Python 2.1 you can import isfunction from the inspect module.

因为Python 2.1可以从检查模块导入isfunction。

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

#4


47  

The accepted answer was at the time it was offered thought to be correct. As it turns out, there is no substitute for callable(), which is back in Python 3.2: Specifically, callable() checks the tp_call field of the object being tested. There is no plain Python equivalent. Most of the suggested tests are correct most of the time:

被接受的答案在当时被认为是正确的。事实证明,无法替代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

We can throw a monkey-wrench into this by removing the __call__ from the class. And just to keep things extra exciting, add a fake __call__ to the instance!

我们可以通过将__call__从类中删除来将monkey-扳手放入其中。为了让事情更令人兴奋,添加一个假的__call__到实例!

>>> del Spam.__call__
>>> can_o_spam.__call__ = lambda *args: 'OK?'

Notice this really isn't callable:

请注意,这是不可调用的:

>>> can_o_spam()
Traceback (most recent call last):
  ...
TypeError: 'Spam' object is not callable

callable() returns the correct result:

callable()返回正确的结果:

>>> callable(can_o_spam)
False

But hasattr is wrong:

但hasattr是错误的:

>>> hasattr(can_o_spam, '__call__')
True

can_o_spam does have that attribute after all; it's just not used when calling the instance.

can_o_spam确实具有这个属性;它只是在调用实例时不使用。

Even more subtle, isinstance() also gets this wrong:

更微妙的是,isinstance()也会出错:

>>> isinstance(can_o_spam, collections.Callable)
True

Because we used this check earlier and later deleted the method, abc.ABCMeta caches the result. Arguably this is a bug in abc.ABCMeta. That said, there's really no possible way it could produce a more accurate result than the result than by using callable() itself, since the typeobject->tp_call slot method is not accessible in any other way.

因为我们之前使用了这个检查,然后删除了这个方法,abc。ABCMeta缓存结果。可以说这是abcmeta的一个错误。也就是说,实际上没有可能比使用callable()本身产生更精确的结果,因为typeobject->tp_call slot方法在任何其他方面都是不可访问的。

Just use callable()

只使用可调用的()

#5


31  

The following should return a boolean:

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

callable(x)

#6


21  

Python's 2to3 tool (http://docs.python.org/dev/library/2to3.html) suggests:

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

import collections
isinstance(obj, collections.Callable)

It seems this was chosen instead of the hasattr(x, '__call__') method because of http://bugs.python.org/issue7006.

看起来这是被选择的,而不是hasattr(x, '__call__')方法,因为http://bugs.python.org/e7006。

#7


17  

callable(x) will return true if the object passed can be called in Python, but the function does not exist in Python 3.0, and properly speaking will not distinguish between:

如果传递的对象可以在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)

You'll get <class 'A'> True and <type function> True as output.

你会得到 True和 True作为输出。

isinstance works perfectly well to determine if something is a function (try isinstance(b, types.FunctionType)); if you're really interested in knowing if something can be called, you can either use hasattr(b, '__call__') or just try it.

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

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

This, of course, won't tell you whether it's callable but throws a TypeError when it executes, or isn't callable in the first place. That may not matter to you.

当然,这不会告诉您它是可调用的,而是在执行时抛出一个类型错误,或者一开始就不能调用。这对你来说可能无关紧要。

#8


9  

If you want to detect everything that syntactically looks like a function: a function, method, built-in fun/meth, lambda ... but exclude callable objects (objects with __call__ method defined), then try this one:

如果您想要检测所有语法看起来像函数的东西:函数、方法、内置的乐趣/冰毒,……但排除可调用对象(定义了__call__方法的对象),然后尝试以下方法:

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

I compared this with the code of is*() checks in inspect module and the expression above is much more complete, especially if your goal is filtering out any functions or detecting regular properties of an object.

我将此与检查模块中is*()检查的代码进行比较,上面的表达式更完整,特别是如果您的目标是过滤掉任何函数或检测对象的正则属性。

#9


6  

Try using callable(x).

尝试使用可调用(x)。

#10


4  

Here's a couple of other ways:

这里有一些其他的方法:

def isFunction1(f) :
    return type(f) == type(lambda x: x);

def isFunction2(f) :
    return 'function' in str(type(f));

Here's how I came up with the second:

下面是我的第二个想法:

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

#11


4  

Since classes also have __call__ method, I recommend another solution:

由于类也有__call__方法,我推荐另一个解决方案:

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

#12


3  

A function is just a class with a __call__ method, so you can do

函数只是一个带有__call__方法的类,所以您可以这样做。

hasattr(obj, '__call__')

For example:

例如:

>>> hasattr(x, '__call__')
True

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

That is the "best" way of doing it, but depending on why you need to know if it's callable or note, you could just put it in a try/execpt block:

这是最好的方法,但这取决于你为什么需要知道它是可调用的还是注意的,你可以把它放在try/execpt块中:

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

It's arguable if try/except is more Python'y than doing if hasattr(x, '__call__'): x().. I would say hasattr is more accurate, since you wont accidently catch the wrong TypeError, for example:

如果尝试/只是比使用hasattr(x, '__call__'): x(),它是有争议的。我认为hasattr更加准确,因为您不会意外地捕获错误的类型错误,例如:

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

#13


3  

Instead of checking for '__call__' (which is not exclusive to functions), you can check whether a user-defined function has attributes func_name, func_doc, etc. This does not work for methods.

您可以检查用户定义的函数是否具有属性func_name、func_doc等功能,而不是检查“__call__”(这不是函数的专有名称)。

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

Another way of checking is using the isfunction() method from the inspect module.

另一种检查方法是使用来自检查模块的isfunction()方法。

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

To check if an object is a method, use inspect.ismethod()

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

#14


3  

Note that Python classes are also callable.

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

To get functions (and by functions we mean standard functions and lambdas) use:

为了得到函数(以及函数,我们指的是标准函数和lambdas):

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)

#15


2  

Whatever function is a class so you can take the name of the class of instance x and compare:

无论什么函数是类,你都可以取实例x的名称,然后比较:


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

#16


2  

The solutions using hasattr(obj, '__call__') and callable(.) mentioned in some of the answers have a main drawback: both also return True for classes and instances of classes with a __call__() method. Eg.

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

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

One proper way of checking if an object is a user-defined function (and nothing but a that) is to use isfunction(.):

检查对象是否为用户定义函数的一种正确方法是使用isfunction(。)

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

If you need to check for other types, have a look at inspect — Inspect live objects.

如果您需要检查其他类型,请查看检查活动对象。

#17


2  

If you have learned C++, you must be familiar with function object or functor, means any object that can be called as if it is a function.

如果你学过c++,你必须熟悉函数对象或函数,意味着任何可以被调用的对象,就像它是一个函数一样。

In C++, an ordinary function is a function object, and so is a function pointer; more generally, so is an object of a class that defines operator(). In C++11 and greater, the lambda expression is the functor too.

在c++中,一个普通的函数是一个函数对象,一个函数指针;更一般地说,一个类的对象定义了运算符()。在c++ 11中,lambda表达式也是函数。

Similarity, in Python, those functors are all callable. An ordinary function can be callable, a lambda expression can be callable, a functional.partial can be callable, the instances of class with a __call__() method can be callable.

在Python中,这些函数都是可调用的。一个普通的函数可以是可调用的,一个lambda表达式可以是可调用的,一个函数。部分可以是可调用的,具有__call__()方法的类实例是可调用的。


Ok, go back to question : I have a variable, x, and I want to know whether it is pointing to a function or not.

好,回到问题:我有一个变量x,我想知道它是否指向一个函数。

If you want to judge weather the object acts like a function, then the callable method suggested by @John Feminella is ok.

如果你想判断天气,对象的作用就像一个函数,那么@John ella建议的callable方法就可以了。

If you want to judge whether a object is just an ordinary function or not( not a callable class instance, or a lambda expression), then the xtypes.XXX suggested by @Ryan is a better choice.

如果您想判断一个对象是否只是一个普通的函数(不是可调用的类实例,或者是lambda表达式),那么xtypes。@Ryan建议的是一个更好的选择。

Then I do an experiment using those code:

#!/usr/bin/python3
# 2017.12.10 14:25:01 CST
# 2017.12.10 15:54:19 CST

import functools
import types
import pprint

Define a class and an ordinary function.

定义一个类和一个普通函数。

class A():
    def __call__(self, a,b):
        print(a,b)
    def func1(self, a, b):
        print("[classfunction]:", a, b)
    @classmethod
    def func2(cls, a,b):
        print("[classmethod]:", a, b)
    @staticmethod
    def func3(a,b):
        print("[staticmethod]:", a, b)

def func(a,b):
    print("[function]", a,b)

Define the functors:

定义子:

#(1.1) built-in function
builtins_func = open
#(1.2) ordinary function
ordinary_func = func
#(1.3) lambda expression
lambda_func  = lambda a : func(a,4)
#(1.4) functools.partial
partial_func = functools.partial(func, b=4)

#(2.1) callable class instance
class_callable_instance = A()
#(2.2) ordinary class function
class_ordinary_func = A.func1
#(2.3) bound class method
class_bound_method = A.func2
#(2.4) static class method
class_static_func = A.func3

Define the functors' list and the types' list:

定义函数列表和类型列表:

## list of functors
xfuncs = [builtins_func, ordinary_func, lambda_func, partial_func, class_callable_instance, class_ordinary_func, class_bound_method, class_static_func]
## list of type
xtypes = [types.BuiltinFunctionType, types.FunctionType, types.MethodType, types.LambdaType, functools.partial]

Judge wether the functor is callable. As you can see, they all are callable.

判断该函子是否可调用。如您所见,它们都是可调用的。

res = [callable(xfunc)  for xfunc in xfuncs]
print("functors callable:")
print(res)

"""
functors callable:
[True, True, True, True, True, True, True, True]
"""

Judge the functor's type( types.XXX). Then the types of functors are not all the same.

判断函数的类型(类型:xxx)。然后,函数的类型并不完全相同。

res = [[isinstance(xfunc, xtype) for xtype in xtypes] for xfunc in xfuncs]

## output the result
print("functors' types")
for (row, xfunc) in zip(res, xfuncs):
    print(row, xfunc)

"""
functors' types
[True, False, False, False, False] <built-in function open>
[False, True, False, True, False] <function func at 0x7f1b5203e048>
[False, True, False, True, False] <function <lambda> at 0x7f1b5081fd08>
[False, False, False, False, True] functools.partial(<function func at 0x7f1b5203e048>, b=4)
[False, False, False, False, False] <__main__.A object at 0x7f1b50870cc0>
[False, True, False, True, False] <function A.func1 at 0x7f1b5081fb70>
[False, False, True, False, False] <bound method A.func2 of <class '__main__.A'>>
[False, True, False, True, False] <function A.func3 at 0x7f1b5081fc80>
"""

I draw a table of callable functor's types using the data.

如何检测Python变量是否为函数?

Then you can choose the functors' types that suitable.

然后,您可以选择合适的函数类型。

such as:

如:

def func(a,b):
    print("[function]", a,b)

>>> callable(func)
True
>>> isinstance(func,  types.FunctionType)
True
>>> isinstance(func, (types.BuiltinFunctionType, types.FunctionType, functools.partial))
True
>>> 
>>> isinstance(func, (types.MethodType, functools.partial))
False

#18


1  

In Python3 I came up with type (f) == type (lambda x:x) which yields True if f is a function and False if it is not. But I think I prefer isinstance (f, types.FunctionType), which feels less ad hoc. I wanted to do type (f) is function, but that doesn't work.

在Python3中,我提出了type (f) == =类型(x:x),如果f是一个函数,则为True,如果不是,则为False。但是我想我更喜欢isinstance (f, types.FunctionType),这感觉不太特别。我想做类型(f)是函数,但这不起作用。

#19


0  

Following previous replies, I came up with this:

在之前的回复中,我想到了以下几点:

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)

#20


0  

If the code will go on to perform the call if the value is callable, just perform the call and catch TypeError.

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

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

#21


-1  

The following is a "repr way" to check it. Also it works with lambda.

下面是一个“repr way”来检查它。它也适用于。

def a():pass
type(a) #<class 'function'>
str(type(a))=="<class 'function'>" #True

b = lambda x:x*2
str(type(b))=="<class 'function'>" #True

#1


608  

If this is for Python 2.x or for Python 3.2+, you can also use callable(). It used to be deprecated, but is now undeprecated, so you can use it again. You can read the discussion here: http://bugs.python.org/issue10518. You can do this with:

如果这是用于Python 2的。对于Python 3.2+,您也可以使用callable()。它曾经被弃用,但现在不被弃用,所以您可以再次使用它。您可以在这里阅读本文的讨论:http://bugs.python.org/e10518。你可以这样做:

callable(obj)

If this is for Python 3.x but before 3.2, check if the object has a __call__ attribute. You can do this with:

如果这是用于python3的。但在3.2之前,检查对象是否具有__call__属性。你可以这样做:

hasattr(obj, '__call__')

The oft-suggested types.FunctionTypes approach is not correct because it fails to cover many cases that you would presumably want it to pass, like with builtins:

oft-suggested类型。函数类型的方法是不正确的,因为它不能覆盖许多您可能希望它通过的情况,比如内置函数:

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

>>> callable(open)
True

The proper way to check properties of duck-typed objects is to ask them if they quack, not to see if they fit in a duck-sized container. Don't use types.FunctionType unless you have a very specific idea of what a function is.

检查鸭子类型对象属性的正确方法是询问它们是否嘎嘎,而不是看它们是否适合于一个鸭子大小的容器。不要使用类型。除非你对函数是什么有一个非常明确的概念。

#2


226  

Builtin types that don't have constructors in the built-in namespace (e.g. functions, generators, methods) are in the types module. You can use types.FunctionType in an isinstance call.

内置名称空间中没有构造函数的构建类型(例如函数、生成器、方法)在类型模块中。您可以使用类型。一个isinstance调用中的函数类型。

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

#3


77  

Since Python 2.1 you can import isfunction from the inspect module.

因为Python 2.1可以从检查模块导入isfunction。

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

#4


47  

The accepted answer was at the time it was offered thought to be correct. As it turns out, there is no substitute for callable(), which is back in Python 3.2: Specifically, callable() checks the tp_call field of the object being tested. There is no plain Python equivalent. Most of the suggested tests are correct most of the time:

被接受的答案在当时被认为是正确的。事实证明,无法替代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

We can throw a monkey-wrench into this by removing the __call__ from the class. And just to keep things extra exciting, add a fake __call__ to the instance!

我们可以通过将__call__从类中删除来将monkey-扳手放入其中。为了让事情更令人兴奋,添加一个假的__call__到实例!

>>> del Spam.__call__
>>> can_o_spam.__call__ = lambda *args: 'OK?'

Notice this really isn't callable:

请注意,这是不可调用的:

>>> can_o_spam()
Traceback (most recent call last):
  ...
TypeError: 'Spam' object is not callable

callable() returns the correct result:

callable()返回正确的结果:

>>> callable(can_o_spam)
False

But hasattr is wrong:

但hasattr是错误的:

>>> hasattr(can_o_spam, '__call__')
True

can_o_spam does have that attribute after all; it's just not used when calling the instance.

can_o_spam确实具有这个属性;它只是在调用实例时不使用。

Even more subtle, isinstance() also gets this wrong:

更微妙的是,isinstance()也会出错:

>>> isinstance(can_o_spam, collections.Callable)
True

Because we used this check earlier and later deleted the method, abc.ABCMeta caches the result. Arguably this is a bug in abc.ABCMeta. That said, there's really no possible way it could produce a more accurate result than the result than by using callable() itself, since the typeobject->tp_call slot method is not accessible in any other way.

因为我们之前使用了这个检查,然后删除了这个方法,abc。ABCMeta缓存结果。可以说这是abcmeta的一个错误。也就是说,实际上没有可能比使用callable()本身产生更精确的结果,因为typeobject->tp_call slot方法在任何其他方面都是不可访问的。

Just use callable()

只使用可调用的()

#5


31  

The following should return a boolean:

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

callable(x)

#6


21  

Python's 2to3 tool (http://docs.python.org/dev/library/2to3.html) suggests:

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

import collections
isinstance(obj, collections.Callable)

It seems this was chosen instead of the hasattr(x, '__call__') method because of http://bugs.python.org/issue7006.

看起来这是被选择的,而不是hasattr(x, '__call__')方法,因为http://bugs.python.org/e7006。

#7


17  

callable(x) will return true if the object passed can be called in Python, but the function does not exist in Python 3.0, and properly speaking will not distinguish between:

如果传递的对象可以在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)

You'll get <class 'A'> True and <type function> True as output.

你会得到 True和 True作为输出。

isinstance works perfectly well to determine if something is a function (try isinstance(b, types.FunctionType)); if you're really interested in knowing if something can be called, you can either use hasattr(b, '__call__') or just try it.

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

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

This, of course, won't tell you whether it's callable but throws a TypeError when it executes, or isn't callable in the first place. That may not matter to you.

当然,这不会告诉您它是可调用的,而是在执行时抛出一个类型错误,或者一开始就不能调用。这对你来说可能无关紧要。

#8


9  

If you want to detect everything that syntactically looks like a function: a function, method, built-in fun/meth, lambda ... but exclude callable objects (objects with __call__ method defined), then try this one:

如果您想要检测所有语法看起来像函数的东西:函数、方法、内置的乐趣/冰毒,……但排除可调用对象(定义了__call__方法的对象),然后尝试以下方法:

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

I compared this with the code of is*() checks in inspect module and the expression above is much more complete, especially if your goal is filtering out any functions or detecting regular properties of an object.

我将此与检查模块中is*()检查的代码进行比较,上面的表达式更完整,特别是如果您的目标是过滤掉任何函数或检测对象的正则属性。

#9


6  

Try using callable(x).

尝试使用可调用(x)。

#10


4  

Here's a couple of other ways:

这里有一些其他的方法:

def isFunction1(f) :
    return type(f) == type(lambda x: x);

def isFunction2(f) :
    return 'function' in str(type(f));

Here's how I came up with the second:

下面是我的第二个想法:

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

#11


4  

Since classes also have __call__ method, I recommend another solution:

由于类也有__call__方法,我推荐另一个解决方案:

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

#12


3  

A function is just a class with a __call__ method, so you can do

函数只是一个带有__call__方法的类,所以您可以这样做。

hasattr(obj, '__call__')

For example:

例如:

>>> hasattr(x, '__call__')
True

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

That is the "best" way of doing it, but depending on why you need to know if it's callable or note, you could just put it in a try/execpt block:

这是最好的方法,但这取决于你为什么需要知道它是可调用的还是注意的,你可以把它放在try/execpt块中:

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

It's arguable if try/except is more Python'y than doing if hasattr(x, '__call__'): x().. I would say hasattr is more accurate, since you wont accidently catch the wrong TypeError, for example:

如果尝试/只是比使用hasattr(x, '__call__'): x(),它是有争议的。我认为hasattr更加准确,因为您不会意外地捕获错误的类型错误,例如:

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

#13


3  

Instead of checking for '__call__' (which is not exclusive to functions), you can check whether a user-defined function has attributes func_name, func_doc, etc. This does not work for methods.

您可以检查用户定义的函数是否具有属性func_name、func_doc等功能,而不是检查“__call__”(这不是函数的专有名称)。

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

Another way of checking is using the isfunction() method from the inspect module.

另一种检查方法是使用来自检查模块的isfunction()方法。

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

To check if an object is a method, use inspect.ismethod()

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

#14


3  

Note that Python classes are also callable.

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

To get functions (and by functions we mean standard functions and lambdas) use:

为了得到函数(以及函数,我们指的是标准函数和lambdas):

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)

#15


2  

Whatever function is a class so you can take the name of the class of instance x and compare:

无论什么函数是类,你都可以取实例x的名称,然后比较:


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

#16


2  

The solutions using hasattr(obj, '__call__') and callable(.) mentioned in some of the answers have a main drawback: both also return True for classes and instances of classes with a __call__() method. Eg.

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

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

One proper way of checking if an object is a user-defined function (and nothing but a that) is to use isfunction(.):

检查对象是否为用户定义函数的一种正确方法是使用isfunction(。)

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

If you need to check for other types, have a look at inspect — Inspect live objects.

如果您需要检查其他类型,请查看检查活动对象。

#17


2  

If you have learned C++, you must be familiar with function object or functor, means any object that can be called as if it is a function.

如果你学过c++,你必须熟悉函数对象或函数,意味着任何可以被调用的对象,就像它是一个函数一样。

In C++, an ordinary function is a function object, and so is a function pointer; more generally, so is an object of a class that defines operator(). In C++11 and greater, the lambda expression is the functor too.

在c++中,一个普通的函数是一个函数对象,一个函数指针;更一般地说,一个类的对象定义了运算符()。在c++ 11中,lambda表达式也是函数。

Similarity, in Python, those functors are all callable. An ordinary function can be callable, a lambda expression can be callable, a functional.partial can be callable, the instances of class with a __call__() method can be callable.

在Python中,这些函数都是可调用的。一个普通的函数可以是可调用的,一个lambda表达式可以是可调用的,一个函数。部分可以是可调用的,具有__call__()方法的类实例是可调用的。


Ok, go back to question : I have a variable, x, and I want to know whether it is pointing to a function or not.

好,回到问题:我有一个变量x,我想知道它是否指向一个函数。

If you want to judge weather the object acts like a function, then the callable method suggested by @John Feminella is ok.

如果你想判断天气,对象的作用就像一个函数,那么@John ella建议的callable方法就可以了。

If you want to judge whether a object is just an ordinary function or not( not a callable class instance, or a lambda expression), then the xtypes.XXX suggested by @Ryan is a better choice.

如果您想判断一个对象是否只是一个普通的函数(不是可调用的类实例,或者是lambda表达式),那么xtypes。@Ryan建议的是一个更好的选择。

Then I do an experiment using those code:

#!/usr/bin/python3
# 2017.12.10 14:25:01 CST
# 2017.12.10 15:54:19 CST

import functools
import types
import pprint

Define a class and an ordinary function.

定义一个类和一个普通函数。

class A():
    def __call__(self, a,b):
        print(a,b)
    def func1(self, a, b):
        print("[classfunction]:", a, b)
    @classmethod
    def func2(cls, a,b):
        print("[classmethod]:", a, b)
    @staticmethod
    def func3(a,b):
        print("[staticmethod]:", a, b)

def func(a,b):
    print("[function]", a,b)

Define the functors:

定义子:

#(1.1) built-in function
builtins_func = open
#(1.2) ordinary function
ordinary_func = func
#(1.3) lambda expression
lambda_func  = lambda a : func(a,4)
#(1.4) functools.partial
partial_func = functools.partial(func, b=4)

#(2.1) callable class instance
class_callable_instance = A()
#(2.2) ordinary class function
class_ordinary_func = A.func1
#(2.3) bound class method
class_bound_method = A.func2
#(2.4) static class method
class_static_func = A.func3

Define the functors' list and the types' list:

定义函数列表和类型列表:

## list of functors
xfuncs = [builtins_func, ordinary_func, lambda_func, partial_func, class_callable_instance, class_ordinary_func, class_bound_method, class_static_func]
## list of type
xtypes = [types.BuiltinFunctionType, types.FunctionType, types.MethodType, types.LambdaType, functools.partial]

Judge wether the functor is callable. As you can see, they all are callable.

判断该函子是否可调用。如您所见,它们都是可调用的。

res = [callable(xfunc)  for xfunc in xfuncs]
print("functors callable:")
print(res)

"""
functors callable:
[True, True, True, True, True, True, True, True]
"""

Judge the functor's type( types.XXX). Then the types of functors are not all the same.

判断函数的类型(类型:xxx)。然后,函数的类型并不完全相同。

res = [[isinstance(xfunc, xtype) for xtype in xtypes] for xfunc in xfuncs]

## output the result
print("functors' types")
for (row, xfunc) in zip(res, xfuncs):
    print(row, xfunc)

"""
functors' types
[True, False, False, False, False] <built-in function open>
[False, True, False, True, False] <function func at 0x7f1b5203e048>
[False, True, False, True, False] <function <lambda> at 0x7f1b5081fd08>
[False, False, False, False, True] functools.partial(<function func at 0x7f1b5203e048>, b=4)
[False, False, False, False, False] <__main__.A object at 0x7f1b50870cc0>
[False, True, False, True, False] <function A.func1 at 0x7f1b5081fb70>
[False, False, True, False, False] <bound method A.func2 of <class '__main__.A'>>
[False, True, False, True, False] <function A.func3 at 0x7f1b5081fc80>
"""

I draw a table of callable functor's types using the data.

如何检测Python变量是否为函数?

Then you can choose the functors' types that suitable.

然后,您可以选择合适的函数类型。

such as:

如:

def func(a,b):
    print("[function]", a,b)

>>> callable(func)
True
>>> isinstance(func,  types.FunctionType)
True
>>> isinstance(func, (types.BuiltinFunctionType, types.FunctionType, functools.partial))
True
>>> 
>>> isinstance(func, (types.MethodType, functools.partial))
False

#18


1  

In Python3 I came up with type (f) == type (lambda x:x) which yields True if f is a function and False if it is not. But I think I prefer isinstance (f, types.FunctionType), which feels less ad hoc. I wanted to do type (f) is function, but that doesn't work.

在Python3中,我提出了type (f) == =类型(x:x),如果f是一个函数,则为True,如果不是,则为False。但是我想我更喜欢isinstance (f, types.FunctionType),这感觉不太特别。我想做类型(f)是函数,但这不起作用。

#19


0  

Following previous replies, I came up with this:

在之前的回复中,我想到了以下几点:

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)

#20


0  

If the code will go on to perform the call if the value is callable, just perform the call and catch TypeError.

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

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

#21


-1  

The following is a "repr way" to check it. Also it works with lambda.

下面是一个“repr way”来检查它。它也适用于。

def a():pass
type(a) #<class 'function'>
str(type(a))=="<class 'function'>" #True

b = lambda x:x*2
str(type(b))=="<class 'function'>" #True