Django:Python全局变量重叠,即使对于单独的运行也是如此

Django:Python全局变量重叠,即使对于单独的运行也是如此,python,django,global-variables,Python,Django,Global Variables,我有一个带有全局变量的Django(so Python)程序: g_variable = [] 我使用了几个函数,在这些函数中,我还更改了值: my_function() global g_variable g_variable.append(some_value) 在我开始多次重复调用该程序之前,这种方法非常有效——在Django中,这意味着我可以快速多次加载该网页。我期望全局变量在每次运行中都是全局的,但事实并非如此。在一次运行中附加到g_变量的值可以在下一次运行中看到

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

g_variable = []
我使用了几个函数,在这些函数中,我还更改了值:

my_function()
    global g_variable 
    g_variable.append(some_value)
在我开始多次重复调用该程序之前,这种方法非常有效——在Django中,这意味着我可以快速多次加载该网页。我期望全局变量在每次运行中都是全局的,但事实并非如此。在一次运行中附加到g_变量的值可以在下一次运行中看到

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

my_function(non_g_variable)
    non_g_variable.append(some_value)
    return non_g_variable
打电话给

non_g_variable = my_function(non_g_variable)

对吗?在我更改所有代码之前,我只想确保没有遗漏任何内容。它将添加许多额外的行并返回调用。

使用全局变量(常量除外),几乎总是容易出错,并且通常生成难以读取的代码。因此,这是一个错误的概念。接收参数、修改并返回参数比动态修改全局变量更明确地说明函数正在做什么


因此,是的,我会继续实施receive-modify-return概念,或者等到有人对您的问题提出了一个特殊的“djangonic”解决方案。

正如其他答案和评论所说,您可能应该重新设计代码以消除全局变量。大致如下:

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():
    ...
但是,有以下几种选择:

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

  • 如果代码运行多线程,则不能使用普通全局变量。并发线程将更新相同的全局变量

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

    如果可能,您的代码应该在任何进程/线程模型中工作

  • 如果代码运行多线程,并且确实希望避免传递
    g_变量
    列表,则可以使用线程局部变量。文件和文件

  • 例如:

    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)
    
    其他链接:


    这就是全局变量在Python中的工作方式。只要web应用程序服务器保持运行,全局状态就会持续


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

    您的问题可以通过在会话中实现一个-缓存的简化解释是-全局变量来解决。

    这个变量在做什么?几乎可以肯定有更好的方法。它是一个表示网页的对象,基本上是所有元素和属性、父子关系等。这在我的代码中都有使用。我需要看一个真实的示例。看起来你正在以一种非常不寻常和非Djangonic的方式构建你的页面。通常,您只需调用单个视图函数来构建上下文,并将其传递给模板进行渲染。这不是Django的事情,也不是我正在构建的模板的html。这是一个给我的网页,然后我必须解析它。一旦它被解析,我就必须以各种方式访问它。因此,我有一些辅助函数,比如is_it_am_image()或包含链接()。这些函数访问基本上包含网页结构的全局变量。我想我可以像上新课一样做。似乎它会涉及同样多的重写,但可能更合适。当有人试图解释线程和局部变量时,总是+1。