Django-admin单例模式和懒加载

05-01 9398阅读 0评论

Django-admin单例模式和懒加载

单例模式

class Foo:
    def __init__(self):
        self.name = "张三"
        
    def __new__(cls, *args, **kwargs):
        empty_object = super().__new__(cls)
        return empty_object
obj1 = Foo()
obj2 = Foo()

当我们实例化对象时,就会在内存开一个空间

python的执行顺序是:

  • 调用__new__方法创建一个空对象
  • 调用__init__方法向空对象中赋值name="张三"
  • 所以称__new__方法为构造方法,__init__方法为初始化方法

    单例模式的目的,就是让我们在创建类对象时,都使用第一次创建的类对象,而不是像上文那样每次使用时都创建一个对象

    例如:

    import admin	# 1
    admin.site		# 2
    import admin	# 3
    admin.site		# 4
    

    python的执行顺序是

    • 1加载admin.py文件

    • 2实例化一个对象

    • 3当我们再次导入admin.py文件时,python不会重新加载,步骤4也就是一开始创建的admin对象,并不会重新创建一个新的对象

      如何实现一个单例模式

      class Foo:
          instance = None
          def __init__(self):
              self.name = "张三"
          def __new__(cls, *args, **kwargs):
              if cls.instance:
                  return cls.instance
              cls.instance = empty_object = super().__new__(cls)
              return empty_object
      obj1 = Foo()
      obj2 = Foo()
      

      这样如果还没有创建实例化的类,instance=None,创建并同时将创建的类赋值给instance

      如果已经创建对象,即instance=对象,就直接返回这个对象

      Django-admin单例模式和懒加载 第1张

      可以看出两个对象的内存地址是一样的

      python实例化创建对象时,不直接创建对象,而是先创建一个代理(不确定是否会使用实例化的功能)

      当我们真正调用实例化的功能的时候,再真正创建对象

      懒加载

      在python中,我们实例化对象后,可以拿到实例化类中的变量,也可以修改

      class Info:
          def __init__(self):
              self.name = "张三"
              self.age = 999
      obj = Info()
      print(obj.name)
      obj.name = "李四"
      print(obj.name)
      

      Django-admin单例模式和懒加载 第2张

      当我们访问一个实例化类中不存在的对象时,一般情况下会报错

      但是如果我们在实例化的类中定义__getattr__方法,如果访问一个实例化类中不存在的对象时,会返回这个方法的return值

      class Info:
          def __init__(self):
              self.name = "张三"
              self.age = 999
          def __getattr__(self, item):
              return "访问了不存在的类变量"
      obj = Info()
      print(obj.xxxxxxxxxxx)
      

      Django-admin单例模式和懒加载 第3张

      django-admin如何实现单例模式和懒加载

      django-admin源码中实例化site对象时,并不会真正实例化创建这个对象

      当它调用register方法时,并没有这个方法,就会执行它的父类LazyObject中的__getattr__方法

      Django-admin单例模式和懒加载 第4张

      Django-admin单例模式和懒加载 第5张

      Django-admin单例模式和懒加载 第6张

      而这里的__getattr__方法实际上时执行new_method_proxy方法

      Django-admin单例模式和懒加载 第7张

      我们需要注意,父类LazyObject中有一个类变量_wrapped默认为None

      Django-admin单例模式和懒加载 第8张

      当我们执行new_method_proxy方法时,会执行_setup()方法并将它赋值给_wrapped

      这样当下次实例化对象时,由于_wrapped不为空,就会直接返回,不会再次创建对象,这就实现了单例模式

      self._wrapped其实就是真正的实例化对象,这就实现了懒加载

      Django-admin单例模式和懒加载 第9张


免责声明
1、本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明。
2、本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所
提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何
损失或损害承担责任。
3、任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。
4、本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在
转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并白负版权等法律责任。

手机扫描二维码访问

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,9398人围观)

还没有评论,来说两句吧...

目录[+]