将 class 弃用为字典属性 python

Deprecate class to dictionary properties python

在 python 中,我有一个 class,它的其中一个属性是保存数据的其他 class,如下所示:

class A:
    class Params:
        def __init__(self):
            self.param1 = None
            self.param2 = None
            ...

    def __init__(self):
        self.parameters = self.Params()

这样,如果有人想更改 self.parameters 中的其中一个参数,他可以写 self.parameters.param1 = ...

我想把保存参数的classParams改成字典

class A:
    def __init__(self):
        self.parameters = {
            'self.param1': None
            'self.param2': None
        }

这样,如果有人想更改任何内容,他可以改为写 self.parameters['param1'] = ...。我已经实施了此更改(在开发分支中)并且它有效。问题是其他人使用该代码,如果我进行此更改,它将破坏他们的代码(这是简单的修复,但仍然如此)。

我想知道是否有什么方法可以做到,如果有人用旧方法(即 parameters.param1 = ...)写,它仍然可以工作,但当他打印一条 DEPRECATED 消息时确实如此,这样我就可以进行过渡 window,让人们从旧方式转向新方式。我想出的唯一方法是,如果我更改属性的名称,我可以保留旧代码并添加一个 log.warning,但我不想更改属性的名称,所以如果有人能想到有办法做到这一点就太好了:)

您可以定义 Params 实现映射协议,然后在属性访问时产生弃用警告。

class Params:
    def __init__(self):
        ...  # As before

    def __setitem__(self, key, value):
        # This check is optional, to prevent creating new attributes
        if not hasattr(self, key):
            raise ValueError(f"No such parameter {key}")
        setattr(self, key, value)

    __getitem__ = getattr

    def __setattr__(self, attr, value):
        warnings.warn("Don't set attributes directly", DeprecationWarning)
        super().__setattr__(attr, value)

    def __getattribute__(self, attr):
        warnings.warn("Don't access attributes directly", DeprecationWarning)
        super().__getattribute__(self, attr)

现在您的下一个版本将支持这两种技术,但属性访问会引发警告。在之后的版本中,可以去掉Paramsclass.

class A:
    def __init__(self):
        self.parameters = {
            'param1': None
            'param2': None
        }