假设我有一个类 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)
最佳答案
您可以将其封装在装饰器中;以下装饰器将调用 before
和 after
如果它们在 self
上可用:
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
然后简单地应用于应该被包装的方法:
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)
装饰器假定它用于方法,例如生成的包装器需要 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)
然后您可以将其应用到您的类(class):
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)
关于python - 如何向类中添加前/后方法。 Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29215759/