本文介绍了如何装饰子类中的所有继承方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
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()
在调用 fetch_page
和 fetch_another_page
时,如何确保自动运行 sanity_check
的 wrapper
Wrapper
类的实例?
How can I make sure that sanity_check
's wrapper
was run automatically when calling fetch_page
and fetch_another_page
on an instance of the Wrapper
class?
推荐答案
如果使用python3.6或更高版本,则可以使用 __ init_subclass __
If using python3.6 or above, you can accomplish this using __init_subclass__
简单的实现:(实际上,您可能想要一个注册表和 functools.wraps
等):
Simple implementation: (for the real thing you probably want a registry and functools.wraps
, etc):
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!
如果您不能更改基类,则可以子类化并创建一个Adapter类:
In case you can't change the baseclass, you can subclass and create an Adapter class:
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
应提供相同的结果.
这篇关于如何装饰子类中的所有继承方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!