Python在重写方法中访问父类的“with”语句

我有一个基类,其方法使用语句with。在子类中,我重写相同的方法,然后希望访问相同的with语句(而不是有两个with语句)。


解决这个问题的标准方法是什么?


有关示例和可能的解决方案,请参见下文。


样品使用threading.Lock


from threading import Lock



class BaseClass:

    def __init__(self):

        self.lock = Lock()

        self._data = 0


    def do_something_locked(self) -> None:

        with self.lock:

            self._data += 5



class ChildClass(BaseClass):

    def do_something_locked(self) -> None:

        super().do_something_locked()

        # Obviously the parent class's self.lock's __exit__ method has 

        # already been called.  What are accepted methods to add more 

        # functionality inside parent class's "with" statement?

        with self.lock:

            self._data += 1

可能的解决方案


我的第一个倾向是定义一个私有方法,如下BaseClass所示:


    def do_something_locked(self) -> None:

        with self.lock:

            self._do_something()


    def _do_something(self) -> None:

        self._data += 5

然后就ChildClass可以覆盖_do_something. 这会工作得很好。


我想知道,还有其他常见的模式来解决这个问题吗?


开心每一天1111
浏览 84回答 2
2回答

慕勒3428872

我的第一个倾向是定义一个私有方法,就像这样BaseClass......然后就ChildClass可以重写_do_something。这会工作得很好。这是解决问题的好方法,即使您没有特殊要求(例如需要保留在with块上下文中)。我不会在“hook”方法名称中使用前导下划线,因为您希望在派生类中重写的任何内容在逻辑上都是类接口的一部分。另外,如果该self._data += 5部分始终需要发生,则将其保留在 中do_something_locked。还有其他常见的模式可以解决这个问题吗?针对该问题,您可以使用可重入锁,如其他答案所示。您还可以忽略类相关的事实,并使用依赖注入 - 在基类中创建一个通用方法,使用锁接受可调用并执行它:# in base classdef do_locked(self, what, *args, **kwargs):    with self.lock:        what(*args, **kwargs)# in derived classdef _implementation(self):    passdef do_interesting_thing(self):    # pass in our own bound method, which takes no arguments    self._do_locked(self._implementation)这种方式允许客户端代码以自定义方式使用锁。如果您不需要或不想要该功能,这可能不是一个好主意。

千巷猫影

使用可重入锁。这将自动“连接”嵌套with语句,仅在最外层之后释放锁with。from threading import RLockclass BaseClass:    def __init__(self):        self.lock = RLock()        self._data = 0    def do_something_locked(self) -> None:        with self.lock:            self._data += 5class ChildClass(BaseClass):    def do_something_locked(self) -> None:        with self.lock:            super().do_something_locked()            self._data += 1一般来说,可重入上下文管理器的模式明确存在以允许可能嵌套的上下文。这些上下文管理器不仅可以在多个 with 语句中使用,而且还可以在已经使用相同上下文管理器的 with 语句内使用。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python