不赞成在 Python 中将类用作父类

Posted

技术标签:

【中文标题】不赞成在 Python 中将类用作父类【英文标题】:Deprecate usage of a class as a parent class in Python 【发布时间】:2012-09-09 19:08:51 【问题描述】:

我正在使用 Python 2.x 框架,该框架的最新版本已将一些广泛使用的基类从模块 A 移动到模块 B(并且这些类已重命名为更清晰的名称正在进行中)。模块A 为新的类名定义了一个向后兼容的标识符。

B.py:

class BaseClass(object):
    __metaclass__ = framework_meta # handles registration etc.

A.py:

import B
oldbase = B.BaseClass

现在为了帮助人们迁移他们的代码,我希望能够在使用框架的代码定义派生自A.oldbase 的类时发出DeprecationWarning(使用warnings.warn),告诉程序员直接继承来自B.BaseClass

我希望这可以通过元类来实现。我试图声明一个从框架元类派生的新元类

class deprecated_base_class(framework_meta):
    def __new__(meta, name, bases, attrs):
        warning = '%(class)s is deprecated'
        for b in bases:
            warning =  getattr(b, '__deprecation_warning__', None) or warning
        warn(warning % 'class': name, DeprecationWarning, stacklevel=2)
        return super(deprecated_base_class, meta).__new__(meta, name, bases, attrs)

与:

A.py:

class oldbase(B.BaseClass):
    __metaclass__ = deprecated_base_class
    __deprecation_warning__ = 'class oldbase is deprecated. Use B.BaseClass instead'

clientcode.py

class FooBar(oldbase):
    pass

我现在遇到的问题是,我得到一个DeprecationWarning 来定义oldbase。我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

如果任何基础被弃用,您希望显示警告:

class deprecated_base_class(framework_meta):
    def __new__(meta, name, bases, attrs):
        for b in bases:
            if isinstance(b, deprecated_base_class):
                warning = getattr(b, '__deprecation_warning__', '%(class)s is deprecated')
                warn(warning % 'class': b.__name__, DeprecationWarning, stacklevel=2)
        return super(deprecated_base_class, meta).__new__(meta, name, bases, attrs)

【讨论】:

以上是关于不赞成在 Python 中将类用作父类的主要内容,如果未能解决你的问题,请参考以下文章

python之类的继承

不能将类引用用作非类型模板参数

是否可以将类用作自己方法的返回类型

在 Python 类中将函数作为属性访问

将类添加到对象1,等待,在for循环中将类添加到对象2

双亲委派模型