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 語句內使用。
添加回答
舉報