懶載入

清风拂山岗(小高同学)發表於2024-10-20

懶載入

當呼叫某個屬性或方法時,相關的資源(如物件例項等)不會立即載入,而是在需要的時候才進行載入,這種策略可以顯著減少記憶體消耗。

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())   

相關文章