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

时间:2010-03-17 01:22:45

标签: python function

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

例如:

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)?是可调用函数,则假设x应返回true,否则返回false。

8 个答案:

答案 0 :(得分:12)

其他答案中提到的callable内置不会回答您提出的问题,因为除了函数之外,它还为方法,类,定义{的类的实例返回True {1}}方法。如果您的问题的标题和文字是错误的,并且您不关心某些事实上是某个功能,但只有当它是可调用的时,那么请使用该内置功能。但是提出的问题的最佳答案是:导入Python标准库的__call__方法,并使用inspect.isfunction。 (还有其他较低抽象的方法,但使用inspect模块的功能进行内省总是一个好主意,而不是低级方法:inspect有助于保持代码简洁,清晰,强大,面向未来。)

答案 1 :(得分:11)

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

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

答案 2 :(得分:7)

python中有callable函数。

 if callable(boda):

答案 3 :(得分:4)

使用callable(boda)确定boda是否可以调用。

Callable意味着这里是一个函数,方法甚至是一个类。但由于你只想区分变量和函数,它应该可以正常工作。

您的代码将如下所示:

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

答案 4 :(得分:2)

>>> import types
>>> def f(): pass
...
>>> x = 0
>>> type(f) == types.FunctionType
True
>>> type(x) == types.FunctionType
False

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

答案 5 :(得分:1)

这不是100%完美的解决方案,但您可能想要查看“可调用的”内置功能:

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

答案 6 :(得分:1)

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

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

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

并且意味着它与三个花车一起使用。但是通过不检查这个,我有一个更有用的功能 - 我可以使用它与int,decimal.Decimals或fractions.Fractions,例如。

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

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

如果你确实有办法处理调用者传入的函数类似的东西(这不仅仅是疯狂的API的结果),那么正确的解决方案就是捕获{当您尝试调用无法调用的内容时引发的{1}}。一般来说,如果失败而不是提前检查,最好尝试做某事并恢复。 (回想一下陈词滥调,“请求宽恕比允许更容易。”)提前检查会导致基于逻辑中的细微错误的意外问题,并可能导致竞争条件。

为什么你认为你需要进行类型检查?

答案 7 :(得分:0)

它应该为property返回什么,你可以像值属性一样访问但实际上调用了一个函数?你看似简单的问题实际上在Python中打开了一大堆蠕虫。这意味着callableisfunction之类的内容对于您的教育和内省很有帮助,但在与其他代码交互时可能不是您想要依赖的内容。

切向:有关如何组合Python的更多信息,请参阅Turtles All The Way Down演示文稿。