如何确定变量是否是Python中的函数?

How to determine if the variable is a function in Python?

本问题已经有最佳答案,请猛点这里访问。

由于函数是Python中的值,如何确定变量是否是函数?

例如:

1
2
3
4
5
boda = len   # boda is the length function now
if ?is_var_function(boda)?:
  print"Boda is a function!"
else:
  print"Boda is not a function!"

这里假设?is_var_function(x)?如果是可调用函数,则返回true;如果不是,则返回false。


其他答案中提到的callable内置项没有回答您提出的问题,因为它还返回True,除了函数之外,还返回定义__call__方法的方法、类、类实例。如果您的问题的标题和文本是错误的,并且您不关心某个东西实际上是否是一个函数,但仅当它是可调用的,那么使用这个内置的。但对于您提出的问题,最好的答案是:导入Python标准库的inspect方法,并使用inspect.isfunction。(还有其他较低的抽象方法,但最好在存在时使用inspect模块的功能进行自省,而不是使用较低级别的方法:inspect有助于保持代码简洁、清晰、健壮和未来的证据)。


您可以使用inspect.isfunction(object)。参见:docs.python.org

也就是说,您应该避免在日常代码中使用这种技术。有时您实际上需要使用反射——例如,MVC框架可能需要加载一个类并检查其成员。但通常您应该返回/传递/处理具有相同"接口"的对象。例如,不要返回可能是整数或函数的对象-总是返回相同的对象"类型",这样代码就可以是一致的。


在Python中有一个可调用函数。

1
 if callable(boda):


callable(boda)判断boda是否可调用。

可调用意味着这里是一个函数、方法甚至是一个类。但是,因为您只想区分变量和函数,所以它应该可以很好地工作。

您的代码如下:

1
2
3
4
5
boda = len   # boda is the length function now
if callable(boda):
  print"Boda is a function!"
else:
  print"Boda is not a function!"

1
2
3
4
5
6
7
8
>>> import types
>>> def f(): pass
...
>>> x = 0
>>> type(f) == types.FunctionType
True
>>> type(x) == types.FunctionType
False

这将检查它是否是一个函数。callable()将检查它是否可调用(即它有一个__call__方法),因此它将在类以及函数或方法上返回true。


在python程序中如何使用不同对象的哲学被称为duck-typing,如果它看起来像鸭子,嘎嘎叫像鸭子,走路像鸭子,它就是鸭子。对象不是按其类型进行分组,而是按其能力进行分组,甚至扩展到函数。在编写Python程序时,您应该始终知道所有对象都能做什么,并且在不进行检查的情况下使用它们。

例如,我可以定义一个函数

1
2
def add_three(a, b c):
    return a + b + c

意味着它可以和三个浮球一起使用。但是不检查这个,我有一个更有用的函数——我可以用它来表示整数、小数、小数,或者分数、分数。

这同样适用于有一个函数。如果我知道我有一个函数并且想调用它,我就应该调用它。也许我所拥有的是一个函数,也许我有一个不同的可调用的(比如一个绑定方法或一个定义__call__的任意类的实例),这可能同样好。通过不检查任何东西,我使我的代码能够处理各种各样的情况,我甚至可能事先没有想到。

在可调用的情况下,我可以非常可靠地确定是否有一个,但是为了代码的简单性,我不想这样做。如果有人传递了一些不可调用的信息,不管怎样,当你调用它时都会出错。如果我编写的代码接受的参数可能是可调用的或不可调用的,并且我根据它做了不同的事情,那么听起来我应该通过定义两个函数来完成这两个不同的事情来改进我的API。

如果您确实有办法处理调用者传入了一些不起作用的东西(这不仅仅是疯狂API的结果),那么正确的解决方案是捕获当您试图调用不能调用的东西时引发的TypeError。一般来说,最好是尝试做些事情,如果失败了就恢复过来,而不是提前检查。(回想一下这个陈词滥调,"请求宽恕比请求允许更容易")提前检查会导致基于逻辑上的细微错误的意想不到的问题,并可能导致种族状况。

你为什么认为你需要打字检查?


这不是一个100%完美的解决方案,但您可能需要检查"可调用"内置函数:

http://docs.python.org/library/functions.html网站


对于像value属性一样访问但实际上调用函数的属性,它应该返回什么?你看似简单的问题实际上在Python中打开了一整罐蠕虫。这意味着像callableisfunction这样的东西对于你的教育和内省是很好的了解,但在与其他代码交互时可能不是你想要依赖的东西。

切切地说:有关如何将Python组合在一起的更多信息,请参见一直向下显示的海龟。