如果您不期望单独使用函数装饰器,实际上您无法完成您想要的事情用户来装饰run
他们自己。您可以使用类装饰器,__init_subclass__ https://www.python.org/dev/peps/pep-0487/, or metaclasses https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/.
有了类装饰器,
class A:
def run(self):
pass
def do_the_other_thing(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
print('doing the other thing!')
return wrapper
def pipeline_thing(cls):
cls.run = do_the_other_thing(cls.run)
# do some other work
return cls
@pipeline_thing
class B(A):
def run(self):
print("running!")
Or with __init_subclass__
class A:
def run(self):
pass
def __init_subclass__(cls):
super().__init_subclass__()
cls.run = do_the_other_thing(cls.run)
# do some other work
class B(A):
def run(self):
print("running!")
Or with metaclasses
class AMeta(type):
def __init__(cls, name, bases, attrs, **kwargs):
super().__init__(name, bases, attrs)
cls.run = do_the_other_thing(cls.run)
# do some other work
class A(metaclass=AMeta):
def run(self):
pass
class B(A):
def run(self):
print("running!")
这个例子对于元类来说太过分了(你正在使用metaclass.__init__
- 元类中最不强大的魔法方法,你的行为可以用__init_subclass__
(这是的预期用途__init_subclass__ https://www.python.org/dev/peps/pep-0487/)。以这种方式使用元类将阻止您的用户使用元类,并且会使您的代码不必要地复杂化。如果您需要管道发挥更多作用,则可以使用它们(例如,如果您需要访问__new__
).
我要么使用__init_subclass__
或类装饰器(@pipe
或其他东西)大概也混合了B
with A
. As, alkasm https://stackoverflow.com/users/5087436/alkasm提到的,你可以使A
继承自abc.ABC
并装饰run
with abc.abstractmethod
确保子类实现它。