【问题标题】:Python decorator to disable a certain function crashingPython装饰器禁用某个功能崩溃
【发布时间】:2018-03-05 18:31:05
【问题描述】:

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

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

装饰器通过将 track 的全局定义替换为不执行任何操作的 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

这个装饰函数的奇怪之处在于我偶尔会崩溃,我想验证这种编码风格是否正确,因为它有点不合常规。

【问题讨论】:

    标签: python django multithreading uwsgi python-decorators


    【解决方案1】:

    您所做的称为猴子修补。虽然不是一个完全不好的做法,但它通常会导致难以查明错误,因此请谨慎使用。

    如果由于某种原因装饰器是强制性的,我建议在装饰器中为请求对象添加一些标志,并在跟踪函数中添加对该标志的检查。

    装饰器:

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

    track函数的开始:

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

    您也可以只评论视图中的线路调用轨迹。

    【讨论】:

    • 感谢您的回答。另外仅供参考,我只会注释掉 track 函数,但实际上它是在视图中的多个其他函数中调用的。这些功能在其他地方被重用,所以不能准确地评论删除它。
    猜你喜欢
    • 1970-01-01
    • 2017-11-19
    • 2013-07-30
    • 2022-01-09
    • 2021-12-05
    • 2023-03-28
    • 2021-12-15
    • 1970-01-01
    • 2021-01-17
    相关资源
    最近更新 更多