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.
你会得到
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 thextypes.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.
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.
你会得到
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 thextypes.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.
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