为啥 django 的设置对象是一个 LazyObject?

Posted

技术标签:

【中文标题】为啥 django 的设置对象是一个 LazyObject?【英文标题】:Why is django's settings object a LazyObject?为什么 django 的设置对象是一个 LazyObject? 【发布时间】:2012-06-29 14:40:29 【问题描述】:

查看 django.conf 我注意到设置是这样实现的:

class LazySettings(LazyObject):     
...

使设置对象变得惰性的原因是什么?

【问题讨论】:

【参考方案1】:

它是一个抽象实际设置文件的代理对象,并使其轻量级,直到您实际访问所需的设置。一旦您开始访问属性,它将按需加载。这个想法是减少加载设置的开销,直到您需要它们。

【讨论】:

目的真的是为了减少开销吗?我的意思是,你显然需要加载设置文件最终,我无法想象任何 django 项目不会,所以延迟加载似乎毫无意义,你不妨这样做开始。【参考方案2】:

我认为目的是从开发人员的角度简化设置。因此,每个项目都可以拥有自己的 settings.py 文件,而无需同时定义所有其他 Django 设置。 LazySettings 包装器类型结合了 Django global_settings.py 和本地设置中的所有内容。它让开发人员可以决定他想要覆盖哪些设置、保留默认设置或添加哪些设置。

LazySettings 类可能是一个错误的名称,因为我认为它并不是真正的懒惰。一旦您执行from django.conf import settings 之类的操作,整个设置对象就在您的范围内。

【讨论】:

【参考方案3】:

查看 Django 编码风格的 this section。原因在那里解释(引用如下)。

除了性能之外,第三方模块可以在导入时修改设置。应延迟访问设置以确保首先进行此配置。

模块通常不应使用存储在 顶层的 django.conf.settings(即在模块评估时 是进口的)。对此的解释如下:

手动配置设置(即不依赖 DJANGO_SETTINGS_MODULE 环境变量)是允许和可能的 如下:

from django.conf import settings

settings.configure(, SOME_SETTING='foo')

但是,如果有任何设置 在 settings.configure 行之前访问,这将不起作用。 (在内部,settings 是一个LazyObject,它自己配置 如果尚未访问设置,则自动访问 已配置)。

所以,如果有一个模块包含一些代码如下:

from django.conf import settings
from django.core.urlresolvers import get_callable

default_foo_view = get_callable(settings.FOO_EXAMPLE_VIEW)

...然后导入 此模块将导致设置对象被配置。那 意味着第三方能够在 ***与配置设置的能力不兼容 手动对象,或在某些情况下使其非常困​​难。

除了上面的代码,还必须有一定程度的惰性或间接性 使用过,如django.utils.functional.LazyObjectdjango.utils.functional.lazy()lambda

【讨论】:

以上是关于为啥 django 的设置对象是一个 LazyObject?的主要内容,如果未能解决你的问题,请参考以下文章

为啥Django时区设置会影响纪元时间?

为啥 Django 模板不能从对象字段中识别列表?

为啥django这样设置就能实现把所有app放到同一个目录?

为啥 DEBUG=False 设置使我的 django 静态文件访问失败?

当我将可选参数传递给视图时,为啥我的 CSS 静态文件在 Django 中不起作用?

为啥在 Django 管理员的 save() 覆盖中将站点添加到对象似乎不起作用?