[Django]-Django: Python global variables overlap, even for separate runs

3👍

You should probably redesign your code to get rid of the global variable, as other answers and comments say. Something along the lines of:

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():
    ...

There are however options:

  1. If your code always runs in a single thread you can fix the problem by setting g_variable to [] between each run. There is probably one top-level function (a Django view function perhaps?) that always marks the start of each run. You should re-initialize the g_variable in this top-level function.

  2. If your code runs multi-threaded, you cannot use a normal global variable. Concurrent threads will update the same global variable.

    Regarding 1 and 2: To run a Django site in a single thread, use manage.py runserver --nothreading for the development server. If you host your site in apache/mod_wsgi, you can control this using daemon mode. Note that you can run multiple single-threaded side-by-side processes. Using a global variable will work in that scenario, since the processes are isolated.

    If possible your code should work in any process/thread model.

  3. If your code runs multi-threaded and you really want to avoid passing around the g_variable list you can use thread-local variables. Documentation here and here.

Example:

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)

Other links:

2👍

That’s how global variables work in Python. The global state persists for as long as the web application server keeps running.

A common solution would be to put your functions in a class, store the per-request state on that class and use a new instance of that class for each request.

1👍

Using global variables, except for constants, is almost always error-prone, and often produces code that is difficult to read. Therefore, it is the wrong concept. Receiving an argument, modifying and returning it is much more explicit about what a function is doing than on-the-fly modification of a global variable.

So yes, I would go ahead and implement the receive-modify-return concept or wait until someone has a special “djangonic” solution to your problem.

0👍

Your problems can be resolved by implementing a cache – a simplified explanation of a cache is – a global variable across a session.

Leave a comment