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

我希望我能做一些像这样的事情:

>>> isinstance(x, function)

但这给了我:

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*()检查代码进行了比较,上面的表达式要完整得多,特别是如果您的目标是过滤任何函数或检测对象的常规属性。

其他回答

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

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)

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

import collections
isinstance(obj, collections.Callable)

这似乎是选择了hasattr(x, '__call__')方法,因为http://bugs.python.org/issue7006。

尝试使用callable(x)。

摘录:

如果对象参数显示为可调用,则返回True,否则返回False。

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

要获得函数(这里的函数指的是标准函数和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)

在内置命名空间中没有构造函数的内置类型(例如函数、生成器、方法)在types模块中。你可以使用类型。isinstance调用中的函数类型:

>>> import types
>>> types.FunctionType
<class 'function'>

>>> def f(): pass

>>> isinstance(f, types.FunctionType)
True
>>> isinstance(lambda x : None, types.FunctionType)
True

注意,这里使用了一个非常具体的“函数”概念,这通常不是您所需要的。例如,它拒绝zip(严格来说是一个类):

>>> type(zip), isinstance(zip, types.FunctionType)
(<class 'type'>, False)

Open(内置函数有不同类型):

>>> type(open), isinstance(open, types.FunctionType)
(<class 'builtin_function_or_method'>, False)

和随机的。Shuffle(技术上是一种隐藏随机的方法。随机实例):

>>> type(random.shuffle), isinstance(random.shuffle, types.FunctionType)
(<class 'method'>, False)

如果你在做一些特定类型的事情。FunctionType实例,如反编译字节码或检查闭包变量,使用类型。FunctionType,但如果你只是需要一个对象像函数一样可调用,请使用callable。