2015-09-05 151 views
0

我爲了記錄目的而構建了一個小裝飾器。檢查方法是否是類方法和調用屬性

def func_detail(func): 
    def func_wrapper(*args,**kwargs): 
     log(func.__name__+' ARGS: {}'.format(str(args))) 
     return func(*args,**kwargs) 
    return func_wrapper 

這適用於對象方法和普通方法。我想在多線程中使用它。我有一個包含pid作爲對象屬性的類。如果它檢測到該方法屬於某個類並且此類包含屬性pid,是否可以將修飾器更改爲logpid

我已經試過:

def func_detail(func): 
    def func_wrapper(*args,**kwargs): 
     log('PID: '+self.pid if self.pid is not None else ' '+func.__name__+' ARGS: {}'.format(str(args))) 
     return func(*args,**kwargs) 
    return func_wrapper 

但這並不是在所有工作。你可以幫幫我嗎?

摘要

我希望能夠調用從那裏方法(func)所屬的class屬性pid沒有傳球self作爲參數傳遞給包裝,因爲在這種情況下它不會工作的方法這些不在類內。

+0

你說這行不通。你的意思是你得到一個屬性錯誤?如果沒有請解釋。 – KobeJohn

+0

@kobejohn例如只是打印 - 打印self.pid NameError:全局名稱'self'未定義這是因爲裝飾器不知道它將用於對象方法。它也可以用於函數之外。 –

回答

3

方法的參數self不會在您的裝飾器中神奇地提供給您的func_wrapper函數。相反,它將成爲您用*args捕獲的頭寸參數中的第一個。如果您想使用它,您需要檢查args[0]並查看它是否具有pid屬性。

試試這個,檢查先說第一個參數存在,那麼,如果它有一個pid屬性:

log('{}FUNC: {} ARGS: {}'.format('PID: {} '.format(args[0].pid) 
           if args and hasattr(args[0], "pid") else '', 
           func.__name__, args)) 
0

如果你調用一個方法,對象本身將是第一個參數,該self在方法實現中。

如果您的修飾器僅適用於方法(定義爲def methodName(self, ...):),則可以在自己中捕獲第一個參數。

然後,您可以嘗試打印self.pid並在沒有任何此類屬性時捕獲異常。由於自由函數和方法之間幾乎沒有區別,我認爲你應該爲自由函數定義兩個裝飾器,另一個爲方法定義,或者定義一個裝飾器參數來表示它是否是方法。

另一種解決方法是檢查參數是否不爲空,如果存在,則輸出args [0] .pid。

相關問題