Từ nguồn Python của 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;
}
}
Nó nói rằng:
- Nếu một đối tượng là một thể hiện của một số lớp thì nó có thể gọi được nếu nó có
__call__
thuộc tính.
- Khác đối tượng
x
là callable iff x->ob_type->tp_call != NULL
Mô tả của tp_call
lĩnh vực :
ternaryfunc tp_call
Một con trỏ tùy chọn đến một hàm thực hiện việc gọi đối tượng. Đây phải là NULL nếu đối tượng không thể gọi được. Chữ ký giống như đối với PyObject_Call (). Lĩnh vực này được kế thừa bởi các kiểu con.
Bạn luôn có thể sử dụng hàm dựng sẵn callable
để xác định xem đối tượng đã cho có thể gọi được hay không; hoặc tốt hơn là chỉ cần gọi nó và bắt TypeError
sau. callable
được xóa trong Python 3.0 và 3.1, sử dụng callable = lambda o: hasattr(o, '__call__')
hoặc isinstance(o, collections.Callable)
.
Ví dụ, triển khai bộ đệm đơn giản:
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
Sử dụng:
@Cached
def ack(x, y):
return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1)
Ví dụ từ thư viện chuẩn, tệp site.py
, định nghĩa tích hợp exit()
và quit()
hàm:
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')