为啥 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.LazyObject
,django.utils.functional.lazy()
或lambda
。
【讨论】:
以上是关于为啥 django 的设置对象是一个 LazyObject?的主要内容,如果未能解决你的问题,请参考以下文章
为啥django这样设置就能实现把所有app放到同一个目录?
为啥 DEBUG=False 设置使我的 django 静态文件访问失败?