什么是将类和子类废弃的首选方法?

3

如何在Python中弃用一个类及其子类?

目前,我认为 __init__() 方法可以达到这个目的,但它不行,因为如果我不在子类上调用 super() 方法,它就不会被调用。

编辑: 我的问题缺少一些信息。

我知道如何使用 warn.warning()

另外,我不想使用装饰器。我只想用它在一个类上,如果该类被调用,就应该警告用户。


2
https://dev59.com/Bmox5IYBdhLWcg3wvWsy - DhruvPathak
1个回答

4
您正在寻找 warnings.warn(message[, category[, stacklevel]]) 发出警告,或者可能忽略它或引发异常。如果给出category参数,则必须是警告类别类(见上文);默认为UserWarning。或者message可以是Warning实例,在这种情况下,将忽略category并使用message.class。在这种情况下,消息文本将为str(message)。如果特定警告因警告过滤器而变为错误,则此函数会引发异常,请参见上文。
来自此处
import functools
import inspect
import os
import warnings


class _DeprecatedDecorator(object):
    MESSAGE = "%s is @deprecated"

    def __call__(self, symbol):
        if not inspect.isclass(symbol):
            raise TypeError("only classes can be @deprecated")

        warnings.filterwarnings('default',
                                message=self.MESSAGE % r'\w+',
                                category=DeprecationWarning)
        return self._wrap_class(symbol)

    def _wrap_class(self, cls):
        previous_ctor = cls.__init__

        @functools.wraps(previous_ctor)
        def new_ctor(*args, **kwargs):
            self._warn(cls.__name__)
            return previous_ctor(*args, **kwargs)

        cls.__init__ = new_ctor
        return cls

    def _warn(self, name):
        warnings.warn(self.MESSAGE % name, DeprecationWarning,
                      stacklevel=self._compute_stacklevel())

    def _compute_stacklevel(self):
        this_file, _ = os.path.splitext(__file__)
        app_code_dir = self._get_app_code_dir()

        def is_relevant(filename):
            return filename.startswith(app_code_dir) and not \
                filename.startswith(this_file)

        stack = self._get_callstack()
        stack.pop(0)  # omit this function's frame

        frame = None
        try:
            for i, frame in enumerate(stack, 1):
                filename = frame.f_code.co_filename
                if is_relevant(filename):
                    return i
        finally:
            del frame
            del stack

        return 0

    def _get_app_code_dir(self):
        import myapplication  # root package for the app
        app_dir = os.path.dirname(myapplication.__file__)
        return os.path.join(app_dir, '')  # ensure trailing slash

    def _get_callstack(self):
        frame = inspect.currentframe()
        frame = frame.f_back  # omit this function's frame

        stack = []
        try:
            while frame:
                stack.append(frame)
                frame = frame.f_back
        finally:
            del frame

        return stack

deprecated = _DeprecatedDecorator()
del _DeprecatedDecorator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接