如何在Python中将self传递给类似方法的对象

时间:2019-04-04 08:39:54

标签: python python-3.7 monkeypatching

如果我使用函数修补类的方法,则该函数的行为类似于方法,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
  • 在上面的示例中,为什么Python决定将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>

1 个答案:

答案 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>)