【发布时间】:2020-05-05 14:48:50
【问题描述】:
我正在尝试编写一个抽象基类A,它将具有一个抽象方法run,预计用户/开发人员将重载该方法。我想强制执行一些“之后”行为以自动应用于派生类B,以便在B.run() 运行它之后,将调用另一个标准方法(在数据管道中,这可能例如提交或回滚事务)。有没有办法做到这一点?
我失败的天真尝试是:
def do_the_other_thing(func):
def wrapper():
func()
print('doing the other thing!')
return wrapper
class A:
@do_the_other_thing
def run(self):
pass
class B(A):
def run(self):
print('running!')
B().run()
>>> 'running!'
>>> #'doing the other thing!' # <--- is there a way to get this?
我当然可以通过创建从非抽象方法A.run 调用的不同抽象方法(例如_run)来实现解决方法,但这不太优雅。
我可以在 2007 年看到 PEP 3124 准确地指定了这个功能,但我找不到任何现代参考。
【问题讨论】:
-
装饰器将在定义时替换您的函数,因此我认为没有任何干净的方法可以知道您的函数已被装饰(以便您可以将其应用于子类)以某种方式制作“标记”;即向函数或类添加属性以供稍后阅读。您可以使用
__init_subclass__循环遍历子类上定义的所有方法,然后将装饰器应用于带有标记的方法。我想您还必须保存要使用的装饰器,也许标记可以是装饰器本身。
标签: python overloading