簡體   English   中英

是否可以在類內部創建裝飾器?

[英]Is it possible to create a decorator inside a class?

或者,也許您可​​以想到我正在嘗試做的另一種解決方案。 基本上,我有一個帶有一堆函數的類,我想將它們包裝在try / except塊中,以攔截KeyboardInterrupt錯誤,因為我有一個整齊地清理每個函數的函數。

我沒有想到可以在每個函數中放置巨大的try catch塊,而是可以創建一個裝飾器來執行此操作,但是我遇到了一些問題。 到目前為止,我有這樣的事情

class MyClass:
    def catch_interrupt(self, func):
        def catcher():
            try:
                func()
            except KeyboardInterrupt:
                self.End()
        return catcher

    @catch_interrupt
    def my_func(self):
        # Start a long process that might need to be interrupted

    def End(self):
        # Cleans up things
        sys.exit()

運行此文件時出現的問題是出現錯誤

TypeError: catch_interrupt() takes exactly 2 arguments (1 given)

這有可能嗎? 有沒有更好的方法,或者我真的應該在每個函數內部放try / except塊嗎?

確實可以在類內創建裝飾器,但是您的實現有問題:

首先, catch_interrupt()不能接受self

@catch_interrupt
def my_func(self):
    # Start a long process that might need to be interrupted

相當於

def my_func(self):
    # Start a long process that might need to be interrupted
my_func = catch_interrupt(my_func)

顯然,這不允許self

其次,從裝飾器返回的內部包裝器函數至少需要將self作為參數,並將其傳遞給func ,因為將裝飾的函數將self作為其第一個參數。

您可能還需要調用內部裝飾器_catch_interrupt以暗示它是供內部使用的。 這不會阻止任何人調用它,但是這是一個好習慣,因為如果在類的實例上調用該行為將是不正確的(例如MyClass().catch_interrupt()將嘗試修飾MyClass實例本身,而您可能不希望這樣做)不想)。


但是,我的建議是改為實現一個上下文管理器,然后由它執行清理。 對於只封裝一組語句的情況,這更像Pythonic,並且如果正確實現它,則實際上也可以將其用作修飾符。

我不確定是否可以按照您提議的性質在類中使用裝飾器。 我認為這與裝飾者自己的目的(可以說是hack)是不合常理的。

try-except塊有什么問題? 您已經將所有清除代碼放入了一個函數中,因此遵循DRY原理。 裝飾器和/或包裝器將通過固定try-except語句包裝您的整個函數來限制錯誤處理的靈活性,而不會提供任何真正的額外好處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM