如果我用函数修补类的方法,该函数的行为就像一个方法,self
作为第一个传递args
。
class Spam:
pass
def eggs( *args ):
return args
Spam.eggs = eggs
spam = Spam()
print( spam.eggs() ) # ---> (<Spam>, )
# all good!
但是,如果我使用 object (带有 .__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>, )
- 在上面的示例中,为什么 Python 决定不再传递
Spam
self
? - 如何让
Spam
self
被传递?
理由:为了缓存返回值,我想修改我的类的函数(实际上使用装饰器而不是猴子补丁 - 但这超出了这个问题的范围)。我不想用函数替换类的方法,而是想使用类对象,因为它允许我保留对象中的状态,而不是尝试使用 lambda 修复所有闭包,从而生成更好的代码s.
最佳答案
这是因为函数对象被作为方法调用,并且仅仅定义 __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>)
关于python - 如何在Python中将 `self`传递给类似方法的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55511445/