如果我使用函数修补类的方法,则该函数的行为类似于方法,self
作为{{1 }}。
args
但是,如果我使用 object (带有class Spam:
pass
def eggs( *args ):
return args
Spam.eggs = eggs
spam = Spam()
print( spam.eggs() ) # ---> (<Spam>, )
# all good!
)实例进行修补,则.__call__
将不再作为参数传递:
self
class Spam:
pass
class Beans:
def __call__( *args ):
return args
Spam.beans = Beans()
spam = Spam()
print( spam.beans() ) # ---> (<Beans>, )
# - not good, I'd expect this to be
# (<Beans>, <Spam>, )
Spam
再传递一次? self
Spam
通过? 合理性:为了缓存返回值,我想修改类的函数(实际上使用装饰器而不是monkeypatching-但这不在此问题的范围之内)。我不想使用函数代替类的方法,而是使用类对象,因为它通过允许我保留对象中的状态而不是尝试使用self
来修复所有闭包来编写更好的代码。 / em>
答案 0 :(得分:0)
这是因为称为方法的是函数对象,仅定义__call__
会使类成为“可调用的”,而不是函数对象(请参见https://docs.python.org/3/reference/datamodel.html)。
要解决此问题,可以使该类成为描述符:
class Spam:
pass
class Beans:
def __call__( *args ):
return args
def __get__(self, instance, owner):
from functools import partial
return partial(self.__call__, instance)
Spam.beans = Beans()
spam = Spam()
print(spam.beans())
获取
(<__main__.Beans object at 0x00000179F17664E0>, <__main__.Spam object at 0x00000179F1757F98>)