我意识到这是一个非常基本的问题。如果这看起来很愚蠢,请参阅下面的免责声明和背景信息!
我经常有一个表示资源的对象 - 例如Redis队列 - 在我的Django应用程序的几个地方使用。但是,不必在每个HTTP请求中调用资源。
我应该:
实例化对象一次,然后将其导入到 相关模块?
或者,在需要它的每个模块中本地实例化对象?
shared.py
from redis import Redis
from rq import Queue
queue = Queue(connection=Redis())
views1.py
from shared import queue
# ... use the queue
views2.py
from shared import queue
# ... use the queue
views1.py
from redis import Redis
from rq import Queue
queue = Queue(connection=Redis())
# ... use the queue
views2.py
from redis import Redis
from rq import Queue
queue = Queue(connection=Redis())
# ... use the queue
我确定这个问题看起来很简单。我意识到这两种方法都有效 - 我真的要求这样才能更好地理解所涉及的基本原理。
这两种方法的含义和后果是什么?在某些情况下使用选项1是否有优势,而在其他情况下使用选项2?
我已经在python的导入系统上读过一些内容,发现这些概念有些令人困惑。我也不完全理解运行Django应用程序的python进程是如何工作的。具体来说,(1)当加载对象时,(2)在python进程的生命周期内是否每个对象都保留在内存中,以及(3)python进程是如何以及是否通过多个HTTP请求持续存在。
提前致谢。
答案 0 :(得分:2)
选项1可能是最好的。这实际上使它成为一个单身人士,可以在任何需要的地方使用。
就您的后续问题而言,模块级别的所有内容都是在该流程中首次导入该模块时执行的。当后续模块导入第一个模块时,它不会再次执行;他们只是获得对同一对象的额外引用。所以在这种情况下,会有一个队列的实例化。只要有对象,对象就会保留在内存中;由于此对象在模块级别实例化并分配给模块级变量,因此实例将在进程持续时间内保留在内存中。
这里有很多关于Django中进程如何工作的问题;可以说虽然这在某种程度上取决于运行它的服务器,但几乎所有运行Django的方法都包含多个进程,每个进程都会持续存在多个请求。同样,在您的情况下,每个服务器进程都有自己的对队列对象的单个引用。