懶載入
當呼叫某個屬性或方法時,相關的資源(如物件例項等)不會立即載入,而是在需要的時候才進行載入,這種策略可以顯著減少記憶體消耗。
拿django-admin
來舉例
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
]
相關知識點
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __getattr__(self, item):
return "__getattr__"
obj = Person("xx", "123")
print(obj.email) #當獲取不到email的時候,會自動呼叫__getattr__方法
底層程式碼
def new_method_proxy(func):
def inner(self, *args):
if (_wrapped := self._wrapped) is empty:
self._setup()
_wrapped = self._wrapped
# 透過getattr去獲取相應的內容
return func(_wrapped, *args)
return inner
class LazyObject:
_wrapped = None
__getattr__ = new_method_proxy(getattr)
class DefaultAdminSite(LazyObject):
def _setup(self):
AdminSiteClass = import_string(apps.get_app_config("admin").default_site)
# 需要的時候才進行載入
self._wrapped = AdminSiteClass()
def __repr__(self):
return repr(self._wrapped)
site = DefaultAdminSite()
當我們自己要使用的時候
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def do_something(self):
return "do_something"
class DefaultAdminSite(LazyObject):
def _setup(self):
self._wrapped = Person("xx", 123)
# obj相當於一個代理
obj = DefaultAdminSite()
# 這裡才會真正的去例項化物件,然後呼叫do_something方法
print(obj.do_something())