为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

开心每一天1111 2023-07-11 14:50:35
我有一个基类,其方法使用语句with。在子类中,我重写相同的方法,然后希望访问相同的with语句(而不是有两个with语句)。解决这个问题的标准方法是什么?有关示例和可能的解决方案,请参见下文。样品使用threading.Lockfrom threading import Lockclass BaseClass:    def __init__(self):        self.lock = Lock()        self._data = 0    def do_something_locked(self) -> None:        with self.lock:            self._data += 5class 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. 这会工作得很好。我想知道,还有其他常见的模式来解决这个问题吗?
查看完整描述

2 回答

?
慕勒3428872

TA贡献1848条经验 获得超6个赞

我的第一个倾向是定义一个私有方法,就像这样BaseClass......然后就ChildClass可以重写_do_something。这会工作得很好。

这是解决问题的好方法,即使您没有特殊要求(例如需要保留在with块上下文中)。我不会在“hook”方法名称中使用前导下划线,因为您希望在派生类中重写的任何内容在逻辑上都是类接口的一部分。另外,如果该self._data += 5部分始终需要发生,则将其保留在 中do_something_locked

还有其他常见的模式可以解决这个问题吗?

针对该问题,您可以使用可重入锁,如其他答案所示。您还可以忽略类相关的事实,并使用依赖注入 - 在基类中创建一个通用方法,使用锁接受可调用并执行它:

# in base class

def do_locked(self, what, *args, **kwargs):

    with self.lock:

        what(*args, **kwargs)


# in derived class

def _implementation(self):

    pass

def do_interesting_thing(self):

    # pass in our own bound method, which takes no arguments

    self._do_locked(self._implementation)

这种方式允许客户端代码以自定义方式使用锁。如果您不需要或不想要该功能,这可能不是一个好主意。


查看完整回答
反对 回复 2023-07-11
?
千巷猫影

TA贡献1829条经验 获得超7个赞

使用可重入锁。这将自动“连接”嵌套with语句,仅在最外层之后释放锁with。


from threading import RLock



class BaseClass:

    def __init__(self):

        self.lock = RLock()

        self._data = 0


    def do_something_locked(self) -> None:

        with self.lock:

            self._data += 5



class ChildClass(BaseClass):

    def do_something_locked(self) -> None:

        with self.lock:

            super().do_something_locked()

            self._data += 1

一般来说,可重入上下文管理器的模式明确存在以允许可能嵌套的上下文。

这些上下文管理器不仅可以在多个 with 语句中使用,而且还可以在已经使用相同上下文管理器的 with 语句内使用。


查看完整回答
反对 回复 2023-07-11
  • 2 回答
  • 0 关注
  • 80 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信