python - 如何装饰子类中的所有继承方法

标签 python python-3.x decorator

class Reader:
    def __init__(self):
        pass

    def fetch_page(self):
        with open('/dev/blockingdevice/mypage.txt') as f:
            return f.read()

    def fetch_another_page(self):
        with open('/dev/blockingdevice/another_mypage.txt') as f:
            return f.read()   

class Wrapper(Reader):
    def __init__(self):
        super().__init__()

    def sanity_check(func):
        def wrapper():
            txt = func()
            if 'banned_word' in txt:
                raise Exception('Device has banned word on it!')
        return wrapper

    @sanity_check
    <how to automatically put this decorator on each function of base class? >

w = Wrapper()
w.fetch_page()
w.fetch_another_page()

Wrapper 类的实例?

最佳答案

如果使用 python3.6 或更高版本,您可以使用 __init_subclass__ 完成此操作

简单实现:(对于真实的东西,您可能需要注册表和 functools.wraps 等):

class Reader:
    def __init_subclass__(cls):
        cls.fetch_page = cls.sanity_check(cls.fetch_page)
        cls.fetch_another_page = cls.sanity_check(cls.fetch_another_page)

    def fetch_page(self):
        return 'banned_word'

    def fetch_another_page(self):
        return 'not a banned word'

class Wrapper(Reader):
    def sanity_check(func):
        def wrapper(*args, **kw):
            txt = func(*args, **kw)
            if 'banned_word' in txt:
                raise Exception('Device has banned word on it!')
            return txt
        return wrapper


演示:

In [55]: w = Wrapper()

In [56]: w.fetch_another_page()
Out[56]: 'not a banned word'

In [57]: w.fetch_page()
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-57-4bb80bcb068e> in <module>()
----> 1 w.fetch_page()
...

Exception: Device has banned word on it!

编辑:如果你不能改 rebase 类,你可以继承并创建一个适配器类:

class Reader:

    def fetch_page(self):
        return 'banned_word'

    def fetch_another_page(self):
        return 'not a banned word'

class ReadAdapter(Reader):
    def __init_subclass__(cls):
        cls.fetch_page = cls.sanity_check(cls.fetch_page)
        cls.fetch_another_page = cls.sanity_check(cls.fetch_another_page)

class Wrapper(ReadAdapter):
    def sanity_check(func):
        def wrapper(*args, **kw):
            txt = func(*args, **kw)
            if 'banned_word' in txt:
                raise Exception('Device has banned word on it!')
            return txt
        return wrapper

应该提供相同的结果。

关于python - 如何装饰子类中的所有继承方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55013817/

相关文章:

python - MacOS "TypeError: ' 模块对象上的 Pipenv 问题不可调用”

python - QTableView 中的虚拟列?

java - <SomeThirdPartyClass>Util == 神对象?

python - 如何在 python 抽象类中创建抽象属性

python - 有没有办法从我从 llama-index 获得的响应中流式传输 Fastapi 中的输出

python 3.7 : How can I read a whole file with readlines() except of the first line?

python - 列出所有连续的子数组

python - 如何对数组中的每一项进行编号?

python-3.x - 运行 tmp() 的结果是什么以及为什么?

python - 什么时候 Py_INCREF?