<p>从Python的源代码<a href="http://svn.python.org/view/python/trunk/Objects/object.c?rev=64962&view=markup" rel="noreferrer">object.c</a>:</p>
<pre class="lang-c prettyprint-override"><code>/* 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;
}
}
</code></pre>
<p>上面写着:</p>
<ol>
<li>如果一个对象是某个类的实例,那么它可以调用iff</em>它有<code>__call__</code>属性。</li>
<li>否则对象<code>x</code>可调用<em>iff</em><code>x->ob_type->tp_call != NULL</code></li>
</ol>
<p><a href="http://docs.python.org/api/type-structs.html" rel="noreferrer">^{<cd4>} field</a>的说明:</p>
<blockquote>
<p><code>ternaryfunc tp_call</code> 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.</p>
</blockquote>
<p>您始终可以使用内置的<code>callable</code>函数来确定给定对象是否可调用;或者更好的方法是调用它并在稍后捕获<code>TypeError</code>。<code>callable</code>在Python 3.0和3.1中被删除,请使用<code>callable = lambda o: hasattr(o, '__call__')</code>或<code>isinstance(o, collections.Callable)</code>。</p>
<p>例如,一个简单的缓存实现:</p>
<pre><code>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
</code></pre>
<p>用法:</p>
<pre><code>@Cached
def ack(x, y):
return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1)
</code></pre>
<p>来自标准库、文件<a href="http://svn.python.org/projects/python/trunk/Lib/site.py" rel="noreferrer">^{<cd10>}</a>、内置<code>exit()</code>和<code>quit()</code>函数的定义的示例:</p>
<pre><code>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')
</code></pre>