Python 什么时候对callable()的调用仍然会失败?

Python 什么时候对callable()的调用仍然会失败?,python,Python,Python 3.6(和)中的 如果返回true,调用仍然可能失败,但如果返回false,调用对象将永远不会成功 在这种情况下,“失败”意味着什么?只是“标准”函数调用失败,如参数不匹配或引发异常?如果有别的意思,那是什么 简言之,在什么情况下可以callable(obj)返回true,但调用obj()失败?首先,任何函数调用都可能失败,这是很正常的。也许您在检查callable和调用它之间对对象进行了变异。或者该对象是可调用的,但您向其传递了无效参数,或者该对象在操作过程中引发了异常,或者用户

Python 3.6(和)中的

如果返回true,调用仍然可能失败,但如果返回false,调用对象将永远不会成功

在这种情况下,“失败”意味着什么?只是“标准”函数调用失败,如参数不匹配或引发异常?如果有别的意思,那是什么


简言之,在什么情况下可以
callable(obj)
返回true,但调用
obj()
失败?

首先,任何函数调用都可能失败,这是很正常的。也许您在检查
callable
和调用它之间对对象进行了变异。或者该对象是可调用的,但您向其传递了无效参数,或者该对象在操作过程中引发了异常,或者用户刚刚点击^C

但这并不是文档中警告的内容。他们告诉您,即使
callable(func)
返回了
True,也可以通过执行
func()
得到
TypeError:is not callable

虽然这并没有确切的文档记录(可能是为了允许其他实现优化事情?),但可调用的
基本上实现为:

def callable(object):
    return hasattr(object, '__call__')
如果没有直接说明,这至少是暗示的:

注意类是可调用的(调用一个类会返回一个新实例);如果实例的类具有
\uuu call\uu()
方法,则实例是可调用的

关键是一切都是一个实例。(类是它们的元类的实例,元类总是有一个
\uuu调用\uuu
方法。)


因此,很容易创造出打破测试的东西。一种方法是给它一个不可调用的调用:

>>> class C:
...     __call__ = 0
>>> c = C()
>>> callable(c)
True
>>> c()
TypeError: 'int' object is not callable

另外,请注意,声称错误否定是不可能的(“如果它是错误的,调用对象将永远不会成功”)意味着
\uuuuu call\uuuu
方法上的特殊方法查找必须使用与
callable
相同的机制(或严格较弱的机制)。因此,例如,如果Python实现选择不忽略元类
\uuuuGetAttribute\uuuuuuuuu
查找或实例
\uuuuuuuu dict\uuuuuuuu
查找
\uuuuuuuuuuuu
,则其可调用的
必须执行相同的操作。您可以看到这一点(至少在CPython 3.7中):

(测试其他特殊方法查找的可能性留给读者作为练习,这意味着我懒得把它们全部写下来,并且很高兴地猜测它们都会以同样的方式进行……)


在CPython中,实际上只调用C API方法。只需检查对象的类型是否有
tp\u调用
slot。对于在Python中实现的类型,如果直接在类或基类上定义了
\uuuuu call\uuuuu
,则将是正确的

>>> class D:
...     pass
>>> d = D()
>>> d.__call__ = 0
>>> callable(d)
False
>>> d()
TypeError: 'D' object is not callable