Python 中的 Monkey Patching 使用 super.__init__

Monkey Patching in Python using super.__init__

我想用我自己的 class 猴子修补其他 class。 我尝试使用 Tomonkeypatch.some_func = some_func。它有效,但我想用简洁的方法来做到这一点(即 classes)。

我正在尝试 Monkey 补丁 Message Object in pyrogram

这是我的代码:

import pyrogram

class Message(pyrogram.types.messages_and_media.Message):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    @property
    def test(self):
       return "test"

当我在处理程序中使用代码时

from pyrogram import filters

@client.on_message(filters.private)
async def sometest(client, message):
    s = message.test
    await message.reply(s)
    

我得到:

AttributeError: 'Message' object has no attribute 'test' 

但是,我猴子用热解图修补了?那为什么?

提前谢谢!

您可能应该创建一个新文件,导入 pyrogram.types.Message,然后创建它的子类。

from pyrogram.types import Message

class MyMessage(Message):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    @property
    def test(self):
        return "test"

然后您可以导入自己的 MyMessage 而不是 Pyrograms Message 并像往常一样使用它。

您必须对 pyrogram 使用的原始 Message 对象进行猴子修补。

from pyrogram.types import Message 

@property
def test(self):
       return "test"

Message.test = test

如果你真的想在更改子class时更新消息class(不推荐!)你可以这样做:

from pyrogram.types import Message 

Message.__init_subclass__ = classmethod(lambda sub: [setattr(Message, k, v) for (k,v) in sub.__dict__.items() if k[:2] != '__'])

class MyMessage(Message):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    @property
    def test(self):
        return "test"

毕竟我想为所有想知道的人分享我是如何做到的:

def monkeypatch(obj):
    def wrapper(sub):
        for (func_name, func_) in sub.__dict__.items():
            if func_name[:2] != "__":
                setattr(obj, func_name, func_)
        return sub
    return wrapper

用法:

@monkeypatch(songobj)
class something:
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
    def do_it(self):
        print("just an example")

感谢@yoily-l

这基本上采用了 class 的功能,然后添加到 someobj 属性。