【问题标题】:Class static attribute value shared between requests请求之间共享的类静态属性值
【发布时间】:2015-11-03 10:35:12
【问题描述】:

我有一个静态类属性,它在同一个 http 请求中被修改。

class A:
  x = {}

  def fun(k,v):
    A.x[k] = v

我的问题是,当您执行另一个 http 请求时,上一个请求的最后一个值仍然存在。

我通过 Apache 的 mod WSGI 使用 Django。

我怎样才能使静态值在同一个请求中保持不变,而不是在另一个请求中保持不变?

【问题讨论】:

    标签: python django apache python-2.7 mod-wsgi


    【解决方案1】:

    受泥鱼回答的启发,我实现了一个中间件的 process_response

    import A
    
    class ClearStaticMiddleware(object):
      def process_response(self, request, response):
        A.x = {}
        return response
    

    感谢大家的回复。

    【讨论】:

    • 如果您不使用threading.localA.x 的值将与所有并发请求共享(并且可以在其中一个完成并到达您的中间件时随时清除)。
    【解决方案2】:

    静态变量的全部意义在于它们持久存在于类中,而不是用于处理特定请求的实例中。这在使用线程或基于事件的服务器时很危险,因为静态变量不仅会与下一个请求共享,还会与并行处理的所有请求共享。

    我假设A 类是基于类的视图。在这种情况下,您可以将属性更改为实例:

    class A(…):
        def __init__(self, *args, **kwargs):
            super()
            self.x = {}
    
        def foo(k, v):
            self.x[k] = v
    

    由于基于类的视图会针对它们所服务的每个请求重新实例化,因此该值不会渗透到其他请求中。

    【讨论】:

    • 感谢您的回答,但这不是我的需要,我需要一个在所有类实例之间共享但仅适用于当前请求的变量
    • 在这种情况下,我建议使用threading.local 并使用中间件重置它。但是请注意,通过引入全局状态会使您的应用程序更难测试。
    • Oussama> 需要这样的东西是非常非常罕见的。通常,如果您达到了这一点,则意味着您的代码组织方式存在问题。你应该解决这个问题,而不是试图解决它。
    【解决方案3】:

    每次请求结束时,清空缓存

    @app.teardown_request
    def teardown(exc):
        A.x = {}
    

    【讨论】:

    • 这对我来说是新的,这在视图中吗?还是在课堂上?感谢您的快速回答
    • 它不相信它去哪里重要,但我相信最好去全球范围内的某个地方。 - 我认为装饰器用烧瓶注册函数,所以它不需要在任何地方。 (我猜)
    • 谢谢,在研究之前我从来没有使用过 Flask,看起来很有趣
    • 很抱歉,但这对我来说似乎不是答案,我正在使用 Django,而且flask 似乎是 Django 的替代 Web 框架,而不是我最初认为的 Django 模块。
    猜你喜欢
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多