Python装饰器禁用某个功能崩溃

时间:2017-09-24 19:45:52

标签: python django multithreading uwsgi python-decorators

我在python中有一个在许多视图中使用的函数。特别是它在uwsgi下运行的django应用程序中。该功能只是将跟踪数据激发到我们的数据库中。我想创建一个装饰器,它将禁用该函数以对包含该函数的视图进行特定调用。基本上:

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

装饰器通过用无效的void函数替换track的全局定义来工作。因为我们在uwsgi下运行它,这是多线程的,如果我替换一个全局定义,它将替换在该进程下运行的所有线程的函数,所以我定义了decorator只在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 个答案:

答案 0 :(得分: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 ...

您也可以在视图中注释线路通话。