2017-09-24 68 views
0

我有一個python在許多視圖中使用的函數。特別是它在一個運行在uwsgi下的django應用程序中。該功能只是將跟蹤數據激發到我們的數據庫中。我想創建一個裝飾器來禁用該函數,以便對包含該函數的視圖進行特定的調用。基本上是:Python裝飾器,以禁用某些功能崩潰

@disable tracking 
def view(request): 
    track(request) //disabled by decorator 

裝飾工程通過用無效的void函數替換軌道的全局定義來工作。由於我們正在uwsgi下運行,它是多線程的,如果我替換全局定義,它將替換在進程下運行的所有線程的函數,所以我定義了修飾器只在tid和pid等效時才激活。在這裏:

def disable_tracking(func): 
    #decorator 
    def inner(*args, **kwargs): 
     original_tracker = pascalservice.track.track 
     anon = lambda *args, **kwargs: None 
     tid = lambda : str(current_thread().ident) 
     pid = lambda : str(getpid()) 
     uid = lambda : tid() + pid() 
     current_uid = uid() 
     cache.set(current_uid, True) 
     switcher = lambda *args, **kwargs: anon(*args, **kwargs) if cache.get(uid()) else original_tracker(*args, **kwargs) 
     pascalservice.track.track = switcher 
     result = func(*args, **kwargs) 
     cache.delete(current_uid) 
     pascalservice.track.track = original_tracker 
     return result 
    return inner 

這個裝飾功能的奇怪的事情是,我偶爾會得到一個崩潰,我想驗證,如果這種編碼方式是正確的,因爲這是一個有點標新立異。

回答

1

你在做什麼叫做猴子修補。雖然這不是一個完全不好的做法,但它經常會導致難以查明錯誤,因此請謹慎使用它。

如果由於某種原因裝飾器是強制性的,我會建議在裝飾器中添加一些標誌給請求對象,並在你的軌跡函數中添加一個檢查標誌。

的裝飾:

def disable_tracking(func): 
    def wrapper(*args, **kwargs): 
    kwargs["request"].pascalservice_do_not_track = true 
    return func(*args, **kwargs) 
    return wrapper 

跟蹤功能的開頭:

if hasattr(request, "pascalservice_do_not_track"): 
    return 
# do the tracking ... 

你也可能只是註釋行調用跟蹤在您的視圖。

+0

感謝您的回答。另外,我只是註釋掉軌跡函數,但實際上它在視圖內的多個其他函數內被調用。這些功能在其他地方重複使用,因此無法準確評論,很容易將其刪除。 –