【问题标题】:Monkey-patching class.__str__ using decorator not workingMonkey-patching class.__str__ 使用装饰器不起作用
【发布时间】:2021-10-13 06:23:21
【问题描述】:

我正在尝试通过以下装饰器对类的 __str__ 特殊方法进行猴子修补:

def str_patcher(klass):
    def decorator(*args, **kwargs):
        def __str__(self):
            items = {key: value for key, value in self.__dict__.items() if not key.startswith("_")}
            return f"{type(self).__qualname__}({items})"

        klass.__str__ = __str__
        return klass

    return decorator

然后,我制作了一个由str_patcher装饰的MyClass类:

@str_patcher
class MyClass:
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

但是当我打印出MyClass(a=1, b=2, c=3) 时,我希望看到MyClass({a: 1, b: 2, c: 3}),但我却得到了<class __main__.MyClass>

这是为什么?

【问题讨论】:

  • 您确定要修补__str__,而不是__repr__
  • 哦,我想要补丁__str__首先进行测试。

标签: python python-3.x class python-decorators monkeypatching


【解决方案1】:

你去了一层更深。以下就足够了:

def str_patcher(klass):
    def __str__(self):
        items = {key: value for key, value in self.__dict__.items() if not key.startswith("_")}
        return f"{type(self).__qualname__}({items})"
    klass.__str__ = __str__
    return klass

然后:

@str_patcher
class Foo: pass

foo = Foo()
foo.bar = "baz"
print(foo)
# Foo({'bar': 'baz'})

请注意,您使用了 参数化 装饰器的模式。如果您想为每个装饰的 klass 添加动态内容,这将很有用,但您仍需要对其进行一些更改,例如:

def str_patcher(**kwargs):
    def decorator(klass):
        def __str__(self):
            items = {key: value for key, value in self.__dict__.items() if not key.startswith("_")}
            items.update(kwargs)
            return f"{type(self).__qualname__}({items})"
        klass.__str__ = __str__
        return klass
    return decorator

@str_patcher(funny="stuff")
class Foo: pass

foo = Foo()
foo.bar = "baz"
print(foo)
# Foo({'bar': 'baz', 'funny': 'stuff'})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-28
    • 2017-07-13
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 2016-03-14
    相关资源
    最近更新 更多