Django:Python全局变量重叠,即使是单独的运行

时间:2012-05-21 11:48:32

标签: python django global-variables

我有一个带有全局变量的Django(所以Python)程序:

g_variable = []

我使用这是几个函数,我也改变了值:

my_function()
    global g_variable 
    g_variable.append(some_value)

在我开始多次重复调用程序之前,这很有效 - 在Django中,这意味着我快速加载了多次网页。我预计全局变量在每次运行中都只是全局变量,但事实并非如此。在一次运行中附加到g_variable的值可以在下一次运行中看到。

对我而言,这意味着我现在必须将此变量传递给我的所有函数:

my_function(non_g_variable)
    non_g_variable.append(some_value)
    return non_g_variable

调用
non_g_variable = my_function(non_g_variable)

这是对的吗?在我更改所有代码之前,我只想确保我没有遗漏任何内容。它会添加很多额外的行和返回来电。

4 个答案:

答案 0 :(得分:3)

您应该重新设计代码以摆脱全局变量,正如其他答案和评论所说的那样。有点像:

class WebpageStructure(object):
    def __init__(self, html):
         # parse the html
         self.structure = self.parse(html)
    def contains_link(self):
         # figure it out using self.structure
         return ...

# in the view(s)
webpage = WebpageStructure(html_to_parse)
if webpage.contains_link():
    ...

但有选择:

  1. 如果您的代码始终在单个线程中运行,则可以通过在每次运行之间将g_variable设置为[]来解决问题。可能有一个顶级函数(也许是一个Django视图函数?),它总是标记每次运行的开始。您应该重新初始化此顶级函数中的g_variable

  2. 如果您的代码运行多线程,则无法使用普通的全局变量。并发线程将更新相同的全局变量。

    关于1和2:要在单个线程中运行Django站点,请使用manage.py runserver --nothreading作为开发服务器。如果您在apache / mod_wsgi中托管您的站点,则可以使用daemon mode来控制它。请注意,您可以运行多个单线程并行进程。使用全局变量将在该场景中起作用,因为这些过程是隔离的。

    如果可能,您的代码应该适用于任何进程/线程模型。

  3. 如果您的代码运行多线程,并且您真的想避免传递g_variable列表,则可以使用线程局部变量。文档herehere

  4. 示例:

    import threading
    threadlocal = threading.local()
    
    def mydjangoview(request):
        # In your top-level view function, initialize the list
        threadlocal.g_variable = []
        # Then call the functions that use g_variable
        foo()
        bar()
    
        # ... and then I guess you probably return a response?
        return Response(...)
    
    def foo():
        threadlocal.g_variable.append(some_value)
    
    def bar():
        threadlocal.g_variable.append(some_other_value)
    

    其他链接:

答案 1 :(得分:2)

这就是全局变量在Python中的作用。只要Web应用程序服务器继续运行,全局状态就会持续存在。

一个常见的解决方案是将您的函数放在一个类中,将每个请求状态存储在该类中,并为每个请求使用该类的新实例。

答案 2 :(得分:1)

除了常量之外,使用全局变量几乎总是容易出错,并且经常产生难以阅读的代码。因此,这是错误的概念。接收一个参数,修改并返回它比一个函数正在做的事情要比全局变量的动态修改更明确。

所以是的,我会继续实施接收 - 修改 - 返回概念,或者等到某人有一个特殊的“djangonic”解决方案来解决你的问题。

答案 3 :(得分:0)

通过实施cache可以解决您的问题 - 缓存的简化说明是 - 会话中的全局变量。