3

我有一个带有全局变量的 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

4 回答 4

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列表,您可以使用线程局部变量。此处此处的文档。

例子:

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)

其他链接:

于 2012-05-21T12:30:01.953 回答
2

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

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

于 2012-05-21T12:31:02.017 回答
1

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

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

于 2012-05-21T12:23:39.080 回答
0

您的问题可以通过实现缓存来解决——缓存的简化解释是——跨会话的全局变量。

于 2012-05-21T12:43:33.720 回答