ori*_*ral 2 python oop polymorphism
假设我有一个 A 类,它有很多方法,但我希望它在调用每个方法之前和之后运行某些行。例如:我希望我的类 Dog 在每次调用 bark() 或 run() 时运行 before() 和 after() 。
class Dog():
def __init__(self, sound, speed):
self.sound = sound
self.speed = speed
def before(self):
check_some_things(self)
def after(self):
do_some_things(self)
def bark(self):
sound(self.sound)
def run(self):
move(self.speed)
Run Code Online (Sandbox Code Playgroud)
您可以将其封装在装饰器中;如果这些装饰器在 上可用before,则以下装饰器将调用:afterself
import inspect
from functools import wraps
def before_and_after(f):
@wraps(f)
def wrapper(self, *args, **kw):
if hasattr(self, 'before') and inspect.ismethod(self.before):
self.before()
result = f(self, *args, **kw)
if hasattr(self, 'after') and inspect.ismethod(self.after):
self.after()
return result
return wrapper
Run Code Online (Sandbox Code Playgroud)
然后简单地应用于应该包装的方法:
class Dog():
def __init__(self, sound, speed):
self.sound = sound
self.speed = speed
def before(self):
check_some_things(self)
def after(self):
do_some_things(self)
@before_and_after
def bark(self):
sound(self.sound)
@before_and_after
def run(self):
move(self.speed)
Run Code Online (Sandbox Code Playgroud)
装饰器假设它用于方法,例如生成的包装器期望self作为第一个参数。
如果这需要应用于所有不是before或 的方法after,也许元类是合适的:
class BeforeAfterMeta(type):
def __new__(mcs, classname, bases, body):
for name, value in body.items():
if not inspect.isfunction(value):
continue
if name in ('before', 'after') or name[:2] + name[-2:] == '_' * 4:
# before or after hook, or a special method name like __init__.
continue
body[name] = before_and_after(value)
return super(BeforeAfterMeta, mcs).__new__(mcs, classname, bases, body)
Run Code Online (Sandbox Code Playgroud)
然后您可以将其应用到您的班级:
class Dog(metaclass=BeforeAfterMeta):
def __init__(self, sound, speed):
self.sound = sound
self.speed = speed
def before(self):
check_some_things(self)
def after(self):
do_some_things(self)
def bark(self):
sound(self.sound)
def run(self):
move(self.speed)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3751 次 |
| 最近记录: |