为什么我不能重写使用“dataclasses_json”的“dataclass”对象的“to_dict”方法?

问题描述 投票:0回答:2

dataclasses_json是一个为python的数据类提供JSON功能的库。我注意到重写

to_dict
方法没有效果。这是一个例子:

@dataclass_json
@dataclass
class Message2:
    message: str
    weight: int
    def to_dict(self, encode_json=False):
        print('Custom to_dict')
        ret = {'MESSAGE': self.message, 'WEIGHT': self.weight}
        return ret
m2 = Message2('m2', 2)
print(m2.to_dict())

代码打印以下内容:

{'消息':'m2','重量':2}

在我期待的时候

Custom to_dict
{'MESSAGE': 'm2', 'WEIGHT': 2}

如果删除

@dataclass_json
行,我会得到所需的输出。

所以,我的问题是:

  1. 为什么定义一个函数对

    @dataclass_json
    没有效果,但没有它却可以工作?

  2. 如何覆盖

    to_dict
    并使用
    @dataclass_json

python python-decorators python-dataclasses
2个回答
7
投票
  1. 因为
    dataclass_json
    只是覆盖了你的
    to_dict
    方法here:
    cls.to_dict = DataClassJsonMixin.to_dict
  1. 一种可能的方法是定义一个具有不同名称的方法,并在应用
    dataclass_json
    装饰器后使用此方法来创建
    to_dict
    方法。带装饰器的完整示例:
from dataclasses import dataclass
from dataclasses_json import dataclass_json


def recover_to_dict(cls):
    if hasattr(cls, '_to_dict'):
        setattr(cls, 'to_dict', getattr(cls, '_to_dict'))
    return cls


@recover_to_dict
@dataclass_json
@dataclass
class Message2:
    message: str
    weight: int
    def _to_dict(self, encode_json=False):
        print('Custom to_dict')
        ret = {'MESSAGE': self.message, 'WEIGHT': self.weight}
        return ret
m2 = Message2('m2', 2)
print(m2.to_dict())

0
投票

如果您的自定义 to_dict 想要调用装饰器分配的数据类 to_dict ,事情会变得更加复杂。在这种情况下,您可能希望在类定义之后将生成的函数包装在新函数中。

def custom_to_dict(super_fn):
    @classmethod
    def to_dict(cls, *args, **kwargs):
        fn = super_fn
        # your stuff...
        return fn(*args, *kwargs)
    return to_dict
Message2.to_dict= custom_from_dict(Message2.to_dict)

我确信使用装饰器也可以做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.