在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
消息,这样我就可以人们从旧方法转到新方法的过渡窗口。我想出的唯一方法是,如果我更改属性的名称,则可以保留旧代码并添加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", warnings.DeprecationWarning)
super().__setattr__(attr, value)
def __getattribute__(self, attr):
warnings.warn("Don't access attributes directly", warnings.DeprecationWarning)
super().__getattribute__(self, attr)
现在,您的下一个版本将支持这两种技术,但是属性访问将引发警告。在该版本的[[after中,您可以摆脱Params
类。