Answers:
可调用对象是可以调用的任何东西。
所述内置的可调用(PyCallable_Check在objects.c)检查该参数可以是:
__call__
方法的类的实例或命名的方法__call__
是(根据文档)
当实例被“调用”为函数时调用
class Foo:
def __call__(self):
print 'called'
foo_instance = Foo()
foo_instance() #this is calling the __call__ method
callable
实际告诉您某些东西是否可调用,而进行检查则__call__
告诉您什么都没有;如果一个对象o
提供__getattribute__
或__getattr__
,则hasattr(o, '__call__')
可能返回True,但o
仍将不可调用,因为Python会跳过__getattribute__
和__getattr__
进行调用。EAFP是唯一剩下的检查某项是否可调用的实际方法。
callable()
:“ 此功能首先在Python 3.0中删除,然后在Python 3.2中恢复。 ”
tp_call
检查的存在。请参阅PyCallable_Check的实现,这是3行。
从Python的来源object.c:
/* Test whether an object can be called */
int
PyCallable_Check(PyObject *x)
{
if (x == NULL)
return 0;
if (PyInstance_Check(x)) {
PyObject *call = PyObject_GetAttrString(x, "__call__");
if (call == NULL) {
PyErr_Clear();
return 0;
}
/* Could test recursively but don't, for fear of endless
recursion if some joker sets self.__call__ = self */
Py_DECREF(call);
return 1;
}
else {
return x->ob_type->tp_call != NULL;
}
}
它说:
__call__
属性。x
是可调用的iff x->ob_type->tp_call != NULL
tp_call
领域描述:
ternaryfunc tp_call
指向实现调用对象的函数的可选指针。如果对象不可调用,则应为NULL。签名与PyObject_Call()相同。该字段由子类型继承。
您始终可以使用内置callable
函数来确定给定对象是否可调用;或更好,只是调用它并TypeError
稍后捕获。callable
已在Python 3.0和3.1中删除,请使用callable = lambda o: hasattr(o, '__call__')
或isinstance(o, collections.Callable)
。
示例,一个简单的缓存实现:
class Cached:
def __init__(self, function):
self.function = function
self.cache = {}
def __call__(self, *args):
try: return self.cache[args]
except KeyError:
ret = self.cache[args] = self.function(*args)
return ret
用法:
@Cached
def ack(x, y):
return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1)
来自标准库,文件site.py
,内置定义exit()
和quit()
函数的示例:
class Quitter(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return 'Use %s() or %s to exit' % (self.name, eof)
def __call__(self, code=None):
# Shells like IDLE catch the SystemExit, but listen when their
# stdin wrapper is closed.
try:
sys.stdin.close()
except:
pass
raise SystemExit(code)
__builtin__.quit = Quitter('quit')
__builtin__.exit = Quitter('exit')
def f(): ...
,与类作为对象,例如class C: ...
即f
,''.strip
,len
,和C
所有都调用。__call__()
在类中具有方法的实例相对较少。
可调用对象是允许您使用圆括号()并最终传递一些参数的对象,就像函数一样。
每次定义函数时,python都会创建一个可调用对象。例如,您可以通过以下方式定义函数func(相同):
class a(object):
def __call__(self, *args):
print 'Hello'
func = a()
# or ...
def func(*args):
print 'Hello'
您可以使用此方法代替doit或run之类的方法,我认为看到obj()比obj.doit()更清楚
让我向后解释:
考虑一下...
foo()
...作为以下方面的语法糖:
foo.__call__()
foo
响应的对象在哪里__call__
?当我说任何对象时,我的意思是:内置类型,您自己的类及其实例。
对于内置类型,在编写时:
int('10')
unicode(10)
您实际上是在做:
int.__call__('10')
unicode.__call__(10)
这就是为什么您没有使用foo = new int
Python:只需使class对象在上返回它的一个实例__call__
。我认为Python解决此问题的方式非常优雅。
type(int).__call__(int, '10')
和type(unicode).__call__(unicode, '10')
。总是在类上调用Dunders,而不是通过实例调用。他们也从未经历过元类。在大多数情况下,这只是小问题,但这有时很重要。
Callable是具有该__call__
方法的对象。这意味着您可以伪造可调用的函数,或执行诸如Partial Function Application之类的整洁事情,在该函数中,您可以使用一个函数并添加一些可以增强其功能或填充某些参数的函数,从而返回可以依次调用的函数(在函数式编程圈中称为Currying)。
某些印刷错误将使解释器尝试调用您不想要的内容,例如字符串。在解释器尝试执行不可调用的应用程序时,这可能会产生错误。您可以通过以下类似的脚本来查看在python解释器中发生的情况。
[nigel@k9 ~]$ python
Python 2.5 (r25:51908, Nov 6 2007, 15:55:44)
[GCC 4.1.2 20070925 (Red Hat 4.1.2-27)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 'aaa'() # <== Here we attempt to call a string.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
>>>
在Python中,可调用对象是类型具有__call__
方法的对象:
>>> class Foo:
... pass
...
>>> class Bar(object):
... pass
...
>>> type(Foo).__call__(Foo)
<__main__.Foo instance at 0x711440>
>>> type(Bar).__call__(Bar)
<__main__.Bar object at 0x712110>
>>> def foo(bar):
... return bar
...
>>> type(foo).__call__(foo, 42)
42
就如此容易 :)
这当然可以重载:
>>> class Foo(object):
... def __call__(self):
... return 42
...
>>> f = Foo()
>>> f()
42
检查函数或类的方法是否可调用,这意味着我们可以调用该函数。
Class A:
def __init__(self,val):
self.val = val
def bar(self):
print "bar"
obj = A()
callable(obj.bar)
True
callable(obj.__init___)
False
def foo(): return "s"
callable(foo)
True
callable(foo())
False
callable(obj.__init___)
没有多余的下划线(如AttributeError中所示)吗?如果不是,您确定答案不是True
那个吗?
可调用是带有方法调用的 “内置函数或方法”的类型或类
>>> type(callable)
<class 'builtin_function_or_method'>
>>>
示例: print是一个可调用对象。使用内置函数__call__ 调用print函数时,Python创建类型为print的对象,并调用其方法__call__并传递参数(如果有)。
>>> type(print)
<class 'builtin_function_or_method'>
>>> print.__call__(10)
10
>>> print(10)
10
>>>
谢谢。问候,马里斯
print
函数时,Python创建类型为print的对象并调用其方法__call__
”。Python不会创建打印对象。它只是调用了等同于的东西type(print).__call__(print, *args, **kwargs)
。第一句话没有多大意义。您似乎在混淆可调用对象和“可调用”功能。