2 回答
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)
这种方式允许客户端代码以自定义方式使用锁。如果您不需要或不想要该功能,这可能不是一个好主意。
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 语句内使用。
添加回答
举报