反对类和子类的首选方法是什么

2024-03-29 13:39:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我怎么能在Python中否决一个类及其子类呢?你知道吗

目前我认为__init__()可以工作,但实际上不行,因为如果我不调用子类上的super(),就不会调用它。你知道吗

编辑: 我的问题少了一些信息。你知道吗

我知道如何使用警告。警告()

我也不想用装饰工。我只想在一个类上使用它,如果调用该类,它应该警告用户。你知道吗


Tags: 用户信息编辑警告init装饰子类super
1条回答
网友
1楼 · 发布于 2024-03-29 13:39:56

你在找warnings.warn(message[, category[, stacklevel]])

Issue a warning, or maybe ignore it or raise an exception. The category argument, if given, must be a warning category class (see above); it defaults to UserWarning. Alternatively message can be a Warning instance, in which case category will be ignored and message.class will be used. In this case the message text will be str(message). This function raises an exception if the particular warning issued is changed into an error by the warnings filter see above.

here

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

相关问题 更多 >