现在what a metaclass is已经很清楚了,有一个相关的概念,我一直在使用,但并不知道它的真正含义。
我想每个人都犯过一次括号错误,导致了一个"object is not callable“异常。更重要的是,使用__init__和__new__ lead想知道这个该死的__call__能用来做什么。
你能给我一些解释,包括魔法方法的例子吗?
发布于 2008-09-21 15:44:23
callable是可以调用的任何东西。
built-in (PyCallable_Check in objects.c)检查参数是否为:
__call__方法或结构的类的实例所属的类型具有非空结构(c
名为__call__的方法为(according to the documentation)
实例作为函数‘’调用‘’时调用的
示例
class Foo:
def __call__(self):
print 'called'
foo_instance = Foo()
foo_instance() #this is calling the __call__ method发布于 2008-09-22 15:04:54
来自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;
}
}上面写着:
如果一个对象是某个类的实例,则它是可调用的当且仅当它具有x->ob_type->tp_call != NULL时,
__call__ x对tp_call field的描述
ternaryfunc tp_call一个可选的指针,指向实现对象调用的函数。如果对象不可调用,则该值应为NULL。签名与PyObject_Call()的签名相同。此字段由子类型继承。
您可以始终使用内置的callable函数来确定给定对象是否可调用;或者更好的做法是调用它并在以后捕获TypeError。在Python3.0和3.1中删除了callable,请使用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')发布于 2008-09-26 13:22:20
callable是一个对象,允许您使用圆括号()并最终传递一些参数,就像函数一样。
每次定义函数时,python都会创建一个可调用的对象。在示例中,您可以用以下方式定义函数func (相同):
class a(object):
def __call__(self, *args):
print 'Hello'
func = a()
# or ...
def func(*args):
print 'Hello'你可以使用这个方法而不是像doit或者run这样的方法,我认为看到obj()比obj.doit()更清楚。
https://stackoverflow.com/questions/111234
复制相似问题