Python 元类关键字参数不被子类使用

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

我正在尝试编写一个元类来协助序列化。元类的目的是尽可能地将生产代码与序列化模式(例如 YAML 或 JSON)隔离。因此,事物可以从类

Serializable
继承,而不必(太多)担心它是否会被序列化为 YAML 还是 JSON。

我有以下代码(用于 YAML 序列化程序)。它基本上可以工作,但我想将 Loader 和 Dumper 指定为关键字参数(因为 PyYaml 可以使用 SafeLoader、FullLoader 等),这就是我遇到问题的地方。我向

Serializable
类添加了 Loader 和 Dumper 的关键字参数。这些适用于该类,但不适用于子类,例如当我定义类
A
(它是
Serializable
的子类)时,meteclass 的
__new__
不会获得任何关键字参数。

我是 Python 元类的新手 - 我做错了什么?谢谢。

import yaml

class SerializableMeta(type):
    @classmethod
    def __prepare__(cls, name, bases, **kwargs):
        return {"yaml_tag": None, "to_yaml": None, "from_yaml": None}

    @staticmethod
    def __new__(cls, name, bases, namespace, **kwargs):
        yaml_tag = f"!{name}"
        cls_ = super().__new__(cls, name, bases, namespace)
        cls_.yaml_tag = yaml_tag
        cls_.to_yaml = lambda dumper, obj: dumper.represent_mapping(yaml_tag, obj.__dict__)
        cls_.from_yaml = lambda loader, node: cls_(**loader.construct_mapping(node))
        kwargs["Dumper"].add_representer(cls_, cls_.to_yaml)
        kwargs["Loader"].add_constructor(yaml_tag, cls_.from_yaml)
        return cls_


class Serializable(metaclass=SerializableMeta, Dumper=yaml.Dumper, Loader=yaml.Loader):
    pass


class A(Serializable):
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __repr__(self):
        return f"A({self.a}, {self.b})"

    def __eq__(self, other):
        if isinstance(other, A):
            return self.a == other.a and self.b == other.b
        else:
            return NotImplemented
python-3.x
1个回答
0
投票

您不需要为

@staticmethod
方法使用
__new__
装饰器,请尝试将其删除。

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