Python 从抽象方法继承包装器

Python 从抽象方法继承包装器,python,python-3.x,abstract-class,wrapper,abc,Python,Python 3.x,Abstract Class,Wrapper,Abc,我想系统地包装基类的一些重写方法 我正在使用ABC作为基类。我试图包装@abstractmethod,将注释放在前面或后面,但它不起作用。据我所知,整个包装方法被覆盖 从functools导入包装 从abc导入abc,abstractmethod def打印前(func): @包装(func) def out(*args,**kwargs): 打印('你好') 返回函数(*args,**kwargs) 返回 班级基数(ABC): @打印前 @抽象方法 def测试(自我): 通过 类扩展(基):

我想系统地包装基类的一些重写方法

我正在使用
ABC
作为基类。我试图包装
@abstractmethod
,将注释放在前面或后面,但它不起作用。据我所知,整个包装方法被覆盖

从functools导入包装
从abc导入abc,abstractmethod
def打印前(func):
@包装(func)
def out(*args,**kwargs):
打印('你好')
返回函数(*args,**kwargs)
返回
班级基数(ABC):
@打印前
@抽象方法
def测试(自我):
通过
类扩展(基):
def测试(自我):
打印(“世界”)
下面是我们测试时发生的情况:

Extend().test()
结果:

World
期望的:

Hello
World

我想我没有用正确的方法来获得这种行为。在重写方法之前和之后运行一些代码,什么样的pythonic方式比较好?

正如您所注意到的,decorator不会更改重写的方法。您可以在每次创建子类时装饰该方法。您甚至可以使用magic方法
\uuuu init\u subclass\uuuu
自动完成此操作

class Base(ABC):
    ...

    def __init_subclass__(cls):
        cls.test = print_before(cls.test)
但我不推荐这种方法。它可能会破坏
ABC
机制,如果继承自
Extend
的类不重写该方法,它们将被修饰两次

这里有一个更简单的方法。我们在
Base
上定义了一个具体的“public”方法,该方法调用抽象的“private”方法。在子类中,我们必须实现“private”方法


另一个优点是,您可以更改子类中“包装器”的行为,这对于decorator来说很困难。

正如您所注意到的,decorator不会更改重写的方法。您可以在每次创建子类时装饰该方法。您甚至可以使用magic方法
\uuuu init\u subclass\uuuu
自动完成此操作

class Base(ABC):
    ...

    def __init_subclass__(cls):
        cls.test = print_before(cls.test)
但我不推荐这种方法。它可能会破坏
ABC
机制,如果继承自
Extend
的类不重写该方法,它们将被修饰两次

这里有一个更简单的方法。我们在
Base
上定义了一个具体的“public”方法,该方法调用抽象的“private”方法。在子类中,我们必须实现“private”方法


另一个优点是,您可以更改子类中“包装器”的行为,这对于decorator来说很困难。

谢谢,您的第二个解决方案非常聪明!谢谢,你的第二个解决方案很聪明!