问题:什么是“可赎回”?
既然清楚了什么是元类,就有一个相关的概念,我一直都在使用它,而不知道它的真正含义。
我想每个人都曾因括号错误而导致“对象不可调用”异常。而且,使用__init__
并__new__
导致怀疑这种血腥的__call__
用途。
您能给我一些解释,包括魔术方法的例子吗?
Now that it’s clear what a metaclass is, there is an associated concept that I use all the time without knowing what it really means.
I suppose everybody made once a mistake with parenthesis, resulting in an “object is not callable” exception. What’s more, using __init__
and __new__
lead to wonder what this bloody __call__
can be used for.
Could you give me some explanations, including examples with the magic method ?
回答 0
可调用对象是可以调用的任何东西。
所述内置的可调用(PyCallable_Check在objects.c)检查该参数可以是:
- 具有
__call__
方法的类的实例或
- 具有非null tp_call(c struct)成员的类型,该成员以其他方式指示可调用性(例如在函数,方法等中)
命名的方法__call__
是(根据文档)
当实例被“调用”为函数时调用
例
class Foo:
def __call__(self):
print 'called'
foo_instance = Foo()
foo_instance() #this is calling the __call__ method
A callable is anything that can be called.
The built-in callable (PyCallable_Check in objects.c) checks if the argument is either:
- an instance of a class with a
__call__
method or
- is of a type that has a non null tp_call (c struct) member which indicates callability otherwise (such as in functions, methods etc.)
The method named __call__
is (according to the documentation)
Called when the instance is ”called” as a function
Example
class Foo:
def __call__(self):
print 'called'
foo_instance = Foo()
foo_instance() #this is calling the __call__ method
回答 1
从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')
From Python’s sources 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;
}
}
It says:
- If an object is an instance of some class then it is callable iff it has
__call__
attribute.
- Else the object
x
is callable iff x->ob_type->tp_call != NULL
Desciption of tp_call
field:
ternaryfunc tp_call
An optional
pointer to a function that implements
calling the object. This should be
NULL if the object is not callable.
The signature is the same as for
PyObject_Call(). This field is
inherited by subtypes.
You can always use built-in callable
function to determine whether given object is callable or not; or better yet just call it and catch TypeError
later. callable
is removed in Python 3.0 and 3.1, use callable = lambda o: hasattr(o, '__call__')
or isinstance(o, collections.Callable)
.
Example, a simplistic cache implementation:
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
Usage:
@Cached
def ack(x, y):
return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1)
Example from standard library, file site.py
, definition of built-in exit()
and quit()
functions:
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')
回答 2
可调用对象是允许您使用圆括号()并最终传递一些参数的对象,就像函数一样。
每次定义函数时,python都会创建一个可调用对象。例如,您可以通过以下方式定义函数func(相同):
class a(object):
def __call__(self, *args):
print 'Hello'
func = a()
# or ...
def func(*args):
print 'Hello'
您可以使用此方法代替doit或run之类的方法,我认为看到obj()比obj.doit()更清楚
A callable is an object allows you to use round parenthesis ( ) and eventually pass some parameters, just like functions.
Every time you define a function python creates a callable object.
In example, you could define the function func in these ways (it’s the same):
class a(object):
def __call__(self, *args):
print 'Hello'
func = a()
# or ...
def func(*args):
print 'Hello'
You could use this method instead of methods like doit or run, I think it’s just more clear to see obj() than obj.doit()
回答 3
让我向后解释:
考虑一下…
foo()
…作为以下方面的语法糖:
foo.__call__()
foo
响应的对象在哪里__call__
?当我说任何对象时,我的意思是:内置类型,您自己的类及其实例。
对于内置类型,在编写时:
int('10')
unicode(10)
您实际上是在做:
int.__call__('10')
unicode.__call__(10)
这就是为什么您没有使用foo = new int
Python:只需使class对象在上返回它的一个实例__call__
。我认为Python解决此问题的方式非常优雅。
Let me explain backwards:
Consider this…
foo()
… as syntactic sugar for:
foo.__call__()
Where foo
can be any object that responds to __call__
. When I say any object, I mean it: built-in types, your own classes and their instances.
In the case of built-in types, when you write:
int('10')
unicode(10)
You’re essentially doing:
int.__call__('10')
unicode.__call__(10)
That’s also why you don’t have foo = new int
in Python: you just make the class object return an instance of it on __call__
. The way Python solves this is very elegant in my opinion.
回答 4
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
>>>
A Callable is an object that has the __call__
method. This means you can fake callable functions or do neat things like Partial Function Application where you take a function and add something that enhances it or fills in some of the parameters, returning something that can be called in turn (known as Currying in functional programming circles).
Certain typographic errors will have the interpreter attempting to call something you did not intend, such as (for example) a string. This can produce errors where the interpreter attempts to execute a non-callable application. You can see this happening in a python interpreter by doing something like the transcript below.
[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
>>>
回答 5
__call__
使任何对象都可以作为函数调用。
此示例将输出8:
class Adder(object):
def __init__(self, val):
self.val = val
def __call__(self, val):
return self.val + val
func = Adder(5)
print func(3)
__call__
makes any object be callable as a function.
This example will output 8:
class Adder(object):
def __init__(self, val):
self.val = val
def __call__(self, val):
return self.val + val
func = Adder(5)
print func(3)
回答 6
很简单,“可调用”是可以像方法一样被调用的东西。内置函数“ callable()”将告诉您是否有某些东西可调用,就像检查call属性一样。函数可以像类一样被调用,类实例可以被调用。在这里和这里看到更多关于这个的信息。
Quite simply, a “callable” is something that can be called like a method. The built in function “callable()” will tell you whether something appears to be callable, as will checking for a call property. Functions are callable as are classes, class instances can be callable. See more about this here and here.
回答 7
在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
In Python a callable is an object which type has a __call__
method:
>>> 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
As simple as that :)
This of course can be overloaded:
>>> class Foo(object):
... def __call__(self):
... return 42
...
>>> f = Foo()
>>> f()
42
回答 8
检查函数或类的方法是否可调用,这意味着我们可以调用该函数。
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
To check function or method of class is callable or not that means we can call that function.
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
回答 9
您可以在其后加上“(args)”,并期望它能正常工作。可调用对象通常是方法或类。方法被调用,类被实例化。
It’s something you can put “(args)” after and expect it to work. A callable is usually a method or a class. Methods get called, classes get instantiated.
回答 10
可调用__call__
对象实现特殊方法,因此具有这种方法的任何对象都是可调用的。
callables implement the __call__
special method so any object with such a method is callable.
回答 11
可调用是带有方法调用的 “内置函数或方法”的类型或类
>>> 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
>>>
谢谢。问候,马里斯
Callable is a type or class of “Build-in function or Method” with a method
call
>>> type(callable)
<class 'builtin_function_or_method'>
>>>
Example:
print is a callable object. With a build-in function __call__
When you invoke the print function, Python creates an object of type print and invokes its method __call__ passing the parameters if any.
>>> type(print)
<class 'builtin_function_or_method'>
>>> print.__call__(10)
10
>>> print(10)
10
>>>
Thank you.
Regards,
Maris