django中使用LazyObject实现延迟实例化某个对象,直到真正要用到它的时候才进行初始化。这种设计可以提升性能、减少资源消耗,并避免循环依赖。 django中的实现
# 初始化django配置
django.setup()
def setup(set_prefix=True):
"""
Configure the settings (this happens as a side effect of accessing the
first setting), configure logging and populate the app registry.
Set the thread-local urlresolvers script prefix if `set_prefix` is True.
"""
from django.apps import apps
from django.conf import settings
from django.urls import set_script_prefix
from django.utils.log import configure_logging
configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
if set_prefix:
set_script_prefix(
"/" if settings.FORCE_SCRIPT_NAME is None else settings.FORCE_SCRIPT_NAME
)
# 配置延迟加载
apps.populate(settings.INSTALLED_APPS)
写一个demo来解释
empty = object()
class LazyObject:
"""
A class that allows for lazy initialization of an object.
The object is not created until it is accessed for the first time.
"""
_wrapped = None
def __init__(self):
self._wrapped = empty
def __getattr__(self, name):
if self._wrapped is empty:
self._setup()
return getattr(self._wrapped, name)
def __setattr__(self, name, value):
print(f"Setting attribute {name} to {value}")
if name == '_wrapped':
self.__dict__['_wrapped'] = value
else:
if self._wrapped is empty:
self._setup()
setattr(self._wrapped, name, value)
def _setup(self):
"""
This method should be overridden to initialize the wrapped object.
It is called the first time an attribute is accessed.
"""
raise NotImplementedError("Subclasses must implement _setup method")
class HeavyClass:
def __init__(self):
print("HeavyClass initialized")
self.value = 42
def get_value(self):
return self.value
class LazyHeavyObject(LazyObject):
def _setup(self):
print("Setting up HeavyClass instance")
self._wrapped = HeavyClass()
# Example usage
obj = LazyHeavyObject()
print("LazyHeavyObject created, but HeavyClass not initialized yet.")
# This will trigger the initialization of HeavyClass and print the value.
print("Value from HeavyClass:", obj.get_value())
运行结果
Setting attribute _wrapped to <object object at 0x000001E022534500>
LazyHeavyObject created, but HeavyClass not initialized yet.
Setting up HeavyClass instance
HeavyClass initialized
Setting attribute _wrapped to <__main__.HeavyClass object at 0x000001E022CA7CD0>
Value from HeavyClass: 42