gpt4 book ai didi

python - 从抽象方法继承包装器

转载 作者:行者123 更新时间:2023-12-01 00:35:51 24 4
gpt4 key购买 nike

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

我使用 ABC 作为基类。我尝试包装 @abstractmethod,将注释放在之前或之后,但它不起作用。据我了解,整个包装的方法被重写。

from functools import wraps
from abc import ABC, abstractmethod

def print_before(func):
@wraps(func)
def out(*args, **kwargs):
print('Hello')
return func(*args, **kwargs)

return out

class Base(ABC):
@print_before
@abstractmethod
def test(self):
pass

class Extend(Base):
def test(self):
print('World')

这是我们测试时发生的情况:

Extend().test()

结果:

World

期望:

Hello
World

我想我没有使用正确的方法来获得这种行为。在重写方法之前和之后运行一些代码的Pythonic 方法是什么?

最佳答案

正如您所注意到的,装饰器不会更改重写的方法。您可以在每次创建子类时装饰该方法。您甚至可以使用魔术方法 __init_subclass__ 自动完成此操作。

class Base(ABC):
...

def __init_subclass__(cls):
cls.test = print_before(cls.test)

但我不推荐这种方法。它可能会破坏 ABC 机制,并且从 Extend 继承的类如果不重写该方法,就会被修饰两次。

这是一种更简单的方法。我们在Base上定义了一个具体的“公共(public)”方法,它调用一个抽象的“私有(private)”方法。然后,我们必须在子类中实现“私有(private)”方法。

class Base(ABC):
def test(self):
# do something before
result = self._do_work()
# do something after
return result

@abstractmethod
def _do_work(self):
pass


class Extend(Base):
def _do_work(self):
# your implementation here

# use it like this:
e = Extend()
e.test()

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

关于python - 从抽象方法继承包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57771358/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com