现在,元类是什么已经很清楚了,有一个相关的概念,我一直在使用,但不知道它的真正含义。
我想每个人都犯过一次圆括号错误,导致“对象不可调用”异常。更重要的是,使用__init__和__new__会导致想知道这个该死的__call__可以用来做什么。
你能给我一些解释吗,包括魔术方法的例子?
现在,元类是什么已经很清楚了,有一个相关的概念,我一直在使用,但不知道它的真正含义。
我想每个人都犯过一次圆括号错误,导致“对象不可调用”异常。更重要的是,使用__init__和__new__会导致想知道这个该死的__call__可以用来做什么。
你能给我一些解释吗,包括魔术方法的例子?
当前回答
Callable是带有方法的“内置函数或方法”的类型或类 调用
>>> type(callable)
<class 'builtin_function_or_method'>
>>>
例子: Print是一个可调用对象。使用内置函数调用 当你调用print函数时,Python创建一个print类型的对象,并调用它的方法调用,如果有参数,则传递参数。
>>> type(print)
<class 'builtin_function_or_method'>
>>> print.__call__(10)
10
>>> print(10)
10
>>>
其他回答
可调用对象是任何可以调用的对象。
内置可调用对象(objects.c中的PyCallable_Check)检查参数是否为:
类的实例,具有__call__方法或 具有非空tp_call (c struct)成员的类型,该成员指示可调用性(例如在函数、方法等中)。
名为__call__的方法是(根据文档)
当实例作为函数被“调用”时调用
例子
class Foo:
def __call__(self):
print 'called'
foo_instance = Foo()
foo_instance() #this is calling the __call__ method
很简单,“可调用对象”是可以像方法一样调用的对象。内置函数“callable()”将告诉您某些东西是否看起来是可调用的,就像检查call属性一样。函数和类一样都是可调用的,类实例也是可调用的。看这里和这里。
来自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。 签名与for相同 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')
让我反过来解释:
考虑这个……
foo()
... 作为语法上的糖:
foo.__call__()
其中foo可以是任何响应__call__的对象。当我说任何对象时,我指的是内置类型,你自己的类和它们的实例。
对于内置类型,当你写:
int('10')
unicode(10)
你实际上是在做:
int.__call__('10')
unicode.__call__(10)
这也是Python中没有foo = new int的原因:你只需要让类对象在__call__上返回它的一个实例。在我看来,Python解决这个问题的方式非常优雅。
具有__call__()的类、函数、方法和对象都是可调用的。
你可以用callable()检查是否可调用,如果可调用返回True,如果不可调用返回False,如下所示:
class Class1:
def __call__(self):
print("__call__")
class Class2:
pass
def func():
pass
print(callable(Class1)) # Class1
print(callable(Class2)) # Class2
print(callable(Class1())) # Class1 object
print(callable(Class2())) # Class2 object
print(callable(func)) # func
然后,只有没有__call__()的Class2对象是不可调用的,返回False,如下所示:
True # Class1
True # Class2
True # Class1 object
False # Class2 object
True # func
此外,下面所有的都是不可调用的,返回False,如下所示:
print(callable("Hello")) # "str" type
print(callable(100)) # "int" type
print(callable(100.23)) # "float" type
print(callable(100 + 2j)) # "complex" type
print(callable(True)) # "bool" type
print(callable(None)) # "NoneType"
print(callable([])) # "list" type
print(callable(())) # "tuple" type
print(callable({})) # "dict" type
print(callable({""})) # "set" type
输出:
False # "str" type
False # "int" type
False # "float" type
False # "complex" type
False # "bool" type
False # "NoneType"
False # "list" type
False # "tuple" type
False # "dict" type
False # "set" type