亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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 關注
  • 136 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號