python - 如何向类中添加前/后方法。 Python

标签 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)

最佳答案

您可以将其封装在装饰器中;以下装饰器将调用 beforeafter 如果它们在 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 作为第一个参数。

如果这需要应用于不是beforeafter所有 方法,也许需要一个元类:

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/

相关文章:

php - SOLID 原则中的 SRP 会导致 Lasagna Code 吗?

c++ - 在实例化派生类时指定基类模板参数?

java - 方法重载 int 与 Short

python - 使用导入的模块来引用嵌套模块

python - 从多个 shell 子进程中非阻塞实时读取 (Python)

ruby-on-rails - 如何在 Rails 中使用 "self"关键字

javascript - 创建具有共享变量的对象

c++ - 多级继承和多态

python - Keras: "must compile model before using it"尽管使用了 compile()

python - 最长的元音子串 - Python