在Python中不推荐使用类作为父类

gur*_*lex 7 python inheritance metaclass

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

B.py:

class BaseClass(object):
    __metaclass__ = framework_meta # handles registration etc.
Run Code Online (Sandbox Code Playgroud)

A.py:

import B
oldbase = B.BaseClass
Run Code Online (Sandbox Code Playgroud)

现在,为了帮助人们迁移他们的代码,我希望能够发出一个DeprecationWarning(使用warnings.warn),只要使用框架的代码定义了一个派生于A.oldbase告诉程序员直接继承的类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)
Run Code Online (Sandbox Code Playgroud)

和...一起:

A.py:

class oldbase(B.BaseClass):
    __metaclass__ = deprecated_base_class
    __deprecation_warning__ = 'class oldbase is deprecated. Use B.BaseClass instead'
Run Code Online (Sandbox Code Playgroud)

clientcode.py

class FooBar(oldbase):
    pass
Run Code Online (Sandbox Code Playgroud)

我现在遇到的问题是,我得到了一个DeprecationWarning定义oldbase.我怎样才能解决这个问题?

eca*_*mur 2

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

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)
Run Code Online (Sandbox Code Playgroud)