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

2024-03-29 02:33:00 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我希望我能做些什么:

>>> isinstance(x, function)

但这给了我:

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

我选这个是因为

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

Tags: 函数inmosttypestdinlinefunctioncall
3条回答

内置命名空间中没有构造函数的内置类型(如函数、生成器、方法)位于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

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

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

open(内置函数的类型不同):

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

以及random.shuffle(技术上是隐藏的random.Random实例的方法):

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

如果您正在执行特定于types.FunctionType实例的操作,例如反编译它们的字节码或检查闭包变量,请使用types.FunctionType,但是如果您只需要像函数一样可以调用对象,请使用callable

Since Python 2.1您可以从^{}模块导入isfunction

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

如果这是针对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

检查duck类型对象的属性的正确方法是询问它们是否嘎嘎作响,而不是查看它们是否适合放在duck大小的容器中。不要使用types.FunctionType,除非你对什么是功能有一个非常明确的概念。

相关问题 更多 >