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

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

如果我使用函数修补类的方法,该函数的行为就像一个方法,self作为第一个args传递。

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>, )
  • 在上面的例子中,为什么Python决定更长时间通过Spam self
  • 我怎样才能通过Spam self

基本原理:出于缓存返回值的目的,我想修改我的类的函数(实际上使用装饰器而不是monkeypatching - 但这超出了这个问题的范围)。我不想用函数替换我的类的方法,而是想使用类对象,因为它允许我保留对象中的状态而不是尝试使用lambdas修复所有闭包,从而产生更好的代码。

python python-3.7 monkeypatching
1个回答
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>)
© www.soinside.com 2019 - 2024. All rights reserved.