如何警告类(名称)弃用

发布于 2021-01-29 17:09:16

我已经重命名了作为库一部分的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类,并为其中的所有类方法实现构造函数以及包装器,但是我认为这是更糟糕的解决方案。

关注者
0
被浏览
47
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    也许我可以使OldClsName一个发出警告(记录)并根据其参数构造NewClsName对象(使用 args和*
    kvargs)的函数,但是它看起来不够优雅(或者也许是?)。

    是的,我认为这是非常标准的做法:

    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__捕获对类方法的访问并仍然生成警告,而不会弄乱您的类层次结构。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看