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

标签 python python-3.7 monkeypatching

如果我用函数修补类的方法,该函数的行为就像一个方法,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/

相关文章:

python - 如果名称在列表中,则选择 Pandas 数据框的列,或创建默认值并删除其余列

python - 如何使用 Python MonkeyPatch + Mock 来断言调用了一个函数

javascript - Monkeypatch Javascript 构造函数

javascript - 猴子修补一个 jquery ui 自动完成渲染项目

python - 将 numba 添加到 python 脚本

python - 机器人框架 - "No keyword with name ' 运行进程'被发现”,同时包含进程库

Python - 使用 DataReader 连接数据帧列表

python - pytesseract 不适用于一位数图像

python - 尝试在 python3 中使用 NMAP 扫描一系列 IP

python - pygame 如何从屏幕的每一侧生成敌人?