我已经重命名了作为库一部分的python类。我愿意保留一段时间使用其以前的名称,但想警告用户它已被弃用,将来会被删除。
我认为,为了提供向后兼容性,使用这样的别名就足够了:
class NewClsName:
pass
OldClsName = NewClsName
我不知道如何以一种优雅的方式将
OldClsName
标记为已弃用。也许我可以使OldClsName
一个函数,该函数发出警告(记录日志)并根据其参数构造NewClsName
对象(使用*args
和**kvargs
),但是它看起来不够优雅(或者也许是?)。但是,我不知道Python标准库弃用警告的工作方式。我想可能会有一些不错的魔术来处理弃用问题,例如允许将其视为错误或沉默,具体取决于某些解释程序的命令行选项。
问题是:如何警告用户有关使用过时的类别名(或一般而言过时的类)。
编辑:函数方法对我不起作用(我已经尝试过),因为该类具有某些类方法(工厂方法),当
OldClsName
定义为函数时,这些方法不能调用。以下代码不起作用:class NewClsName(object):
@classmethod
def CreateVariant1( cls, ... ):
pass
@classmethod
def CreateVariant2( cls, ... ):
pass
def OldClsName(*args, **kwargs):
warnings.warn("The 'OldClsName' class was renamed [...]",
DeprecationWarning )
return NewClsName(*args, **kwargs)
OldClsName.CreateVariant1( ... )
因为:
AttributeError: 'function' object has no attribute 'CreateVariant1'
继承是我唯一的选择吗?老实说,在我看来,它看起来不是很干净-它通过引入不必要的派生来影响类的层次结构。另外,
OldClsName is not NewClsName
在大多数情况下不是问题,但是在使用该库编写的代码不好的情况下可能是个问题。我还可以创建一个虚拟的,无关的
OldClsName
类,并为其中的所有类方法实现构造函数以及包装器,但我认为这是更糟糕的解决方案。 最佳答案
是的,我认为这是非常标准的做法:
def OldClsName(*args, **kwargs):
from warnings import warn
warn("get with the program!")
return NewClsName(*args, **kwargs)
唯一棘手的事情是,如果您拥有
OldClsName
的子类的东西-那么我们必须变得聪明。如果只需要继续访问类方法,则应该这样做:class DeprecationHelper(object):
def __init__(self, new_target):
self.new_target = new_target
def _warn(self):
from warnings import warn
warn("Get with the program!")
def __call__(self, *args, **kwargs):
self._warn()
return self.new_target(*args, **kwargs)
def __getattr__(self, attr):
self._warn()
return getattr(self.new_target, attr)
OldClsName = DeprecationHelper(NewClsName)
我还没有测试过,但这应该可以给您一个想法-
__call__
将处理常规实例路线,__getattr__
将捕获对类方法的访问并仍然生成警告,而不会弄乱您的类层次结构。