[英]Inherit wrapper from abstract method
我想系統地包裝一些基類的重寫方法。
我使用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__
自動執行此__init_subclass__
。
class Base(ABC):
...
def __init_subclass__(cls):
cls.test = print_before(cls.test)
但我不會推薦這種方法。 如果不覆蓋該方法,它可能會破壞ABC
機制,並且從Extend
繼承的類會被裝飾兩次。
這是一個更簡單的方法。 我們在Base
上定義了一個具體的“公共”方法,它調用了一個抽象的“私有”方法。 在子類中,我們必須實現“私有”方法。
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()
另一個優點是您可以更改子類中“包裝器”的行為,這對於裝飾器來說是困難的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.