Python 中哪些调用不能调用`__call__`?

问题描述 投票:0回答:1

我的问题的答案可能取决于代码的解释器,尽管我不确定。如果确实如此,那么我会很高兴听到任何广泛使用的 Python 解释器,尤其是 CPython。

如果我为类

__call__
实现
C
方法,那么调用
c
的实例
C
将调用
c.__call__
,然后它可能会依次使用自己的
__call__
方法。然而,很明显,并不是每个可调用对象
c
在一系列调用中被调用时总是使用
c.__call__
,例如考虑的。

举个例子,调用可调用(!)对象

get := vars(cls)["__get__"]
,其中
cls
是类
types.WrapperDescriptorType
,不能总是依赖于
get.__call__
,因为
get
恰好是
cls
类型
call := vars(cls)["__call__"]
也是如此! (如果需要
get.__get__
来获取
get.__call__
,那么获取它就需要在某些时候像
get
一样调用
get(get, get, cls)

实际上,

get.__call__
不会被视为
call.__get__(get, cls)
,而是显然会被视为
get(call, get, cls)
。)

问题。给定一个可调用对象

c
,如何知道它的调用是否总是依赖于
c.__call__

我想要一种可以适用于所有近期版本的 Python 的方法,并且更强烈地需要更健壮的方法。

python protocols python-internals callable-object
1个回答
1
投票

可调用对象在被调用时(即,当您执行 c() 时)的行为由其

__call__
方法定义。然而,仅仅因为一个对象有一个
__call__
方法并不能保证每次调用该对象时都会使用该方法。

造成这种情况的原因有多种,其中一些原因可能是方法重写,如果派生类重写了调用

__call__
方法,那么除非显式调用,否则不会使用该方法。

另一个原因是方法删除,如果调用方法被删除,就会发生这种情况。您可以通过使用这行代码进行检查来检查调用方法的准确性:

import inspect
print(inspect.getsource(c.__call__))

上面的代码行将打印对象 c 的 call 方法的源代码,让您查看它是否是预期的实现。

© www.soinside.com 2019 - 2024. All rights reserved.