首页 > 解决方案 > 弃用类到字典属性python

问题描述

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

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 = ....

我想将Params保存参数的类更改为字典

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

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

我想知道是否有任何方法可以做到,以便如果有人以旧方式(即parameters.param1 = ...)写作,它仍然可以工作,DEPRECATED但当他这样做时会打印一条消息,这样我可以制作一个过渡窗口,人们可以从老路换新路。我想出的唯一方法是如果我更改属性的名称,我可以保留旧代码并添加 a log.warning,但我不想更改属性的名称,所以如果有人能想办法做到这一点那会很好 :)

标签: pythondictionaryoopdeprecated

解决方案


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

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)

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

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

推荐阅读