zoukankan      html  css  js  c++  java
  • 课后练习 第一阶段:Python开发基础 day30 面向对象--单例模式实例

    day30 课后作业

    1.在元类中控制把自定义类的数据属性都变成大写

    class MyMeta(type):
        def __new__(cls,name,bases,attr):
            dic = {}
            for k,v in attr.items():
                if not k.startswith('__'):
                    dic[k.upper()] = v
                else:
                    dic[k] = v
            return type.__new__(cls,name,bases,dic)
    
    class Demo(metaclass=MyMeta):
        name = 'forever'
        age = 18
    
    print(Demo.__dict__)
    

    2.在元类中控制自定义的类无需init方法

    class MyMeta(type):
        def __call__(self, *args, **kwargs):
            obj = object.__new__(self)
            for k,v in kwargs.items():
                obj.__dict__[k] = v
            return obj
    
    class Demo(metaclass=MyMeta):
        name = 'forever'
        age = 18
    
    demo = Demo(name = 'forever',age = 18)
    print(demo.__dict__)
    

    3.在元类中控制,把自定义的类的属性都放到attr字典中

    class MyMeta(type):
        def __new__(cls,name,bases,attr):
            dic = {'attr':{}}
    
            for k,v in attr.items():
                if not k.startswith('__'):
                    dic['attr'][k] = v
                else:
                    dic[k] = v
            return type.__new__(cls,name,bases,dic)
    
    class Demo(metaclass=MyMeta):
        name = 'forever'
        age = 18
    
    print(Demo.__dict__)
    

    4.四种方式实现单例模式

    • 第一种(通过类的绑定方法)

      dic = {'PORT':3306,'HOST':'127.0.0.1'}
      class Demo1():
          _instance = None
          def __init__(self,port,host):
              self.port = port
              self.host = host
      
          @classmethod
          def get_sigoleton(cls):
              if not cls._instance:
                  cls._instance = cls(dic['PORT'],dic['HOST'])
              return cls._instance
      
      s1 = Demo1.get_sigoleton()
      s2 = Demo1.get_sigoleton()
      s3 = Demo1(33306,'192.168.1.1')
      print(s1)
      print(s2)
      print(s3)
      
    • 第二种(通过装饰器)

      • 用户输入端口和地址,实例化产生对象

      • 当用户不输入端口和地址,每次拿到的对象,都是同一个

      dic = {'PORT':3306,'HOST':'127.0.0.1'}
      def get_sigoleton(cls):
          _instance=None
          def wrapper(*args,**kwargs):
              if len(args)!=0 or len(kwargs)!=0:
                  #表示传了参数,生成新对象
                  res=cls(*args,**kwargs)
                  return res
              else:
                  nonlocal _instance
                  if not _instance:
                      _instance=cls(dic['PORT'], dic['HOST'])
                  return _instance
          return wrapper
      
      @get_sigoleton    #会把下面的Sql当中参数传入,相当于:Sql=get_sigoleton(Sql)
      class Sql():
          def __init__(self,port,host):
              self.port=port
              self.host=host
      s1=Sql()
      s2=Sql()
      s3=Sql('33306','192.168.1.1')
      s4=Sql('33306','192.168.1.1')
      print(s1)
      print(s2)
      print(s3)
      
    • 第三种(通过元类)

      • 当用户输入端口和地址,实例化产生新对象
      • 当用户不输入端口和地址,每次拿到的对象,都是同一个
      dicc = {'PORT':'3306','HOST':'127.0.0.1'}
      class Mymeta(type):
          def __init__(self,name,bases,dic):
              #self 是Sql类
      
              #把实例化好的对象,放到了类的名称空间
              self._instance=self(dicc['PORT'], dicc['HOST'])
          def __call__(self, *args, **kwargs):
              #self是谁?是Sql类
              if len(args)!=0 or len(kwargs)!=0:
                  obj=object.__new__(self)
                  obj.__init__(*args, **kwargs)
                  return obj
              else:
                  return self._instance
      
      class Sql(metaclass=Mymeta):    #相当于 Sql=Mymeta(name,bases,dic)   这个会调用 Mymeta的__init__  在里面已经向类的名称空间放了一个对象
          def __init__(self,port,host):
              self.port=port
              self.host=host
      
      print(Sql.__dict__)
      s1=Sql()
      #调用元类的__call__
      s2=Sql()
      s3=Sql('33306','192.168.1.1')
      print(s1)
      print(s2)
      print(s3)
      
    • 第四种(通过模块导入:python中的模块是天然的单例)

      def test():
          from sigonleton import s1
          print(s1.port)
          print(s1)
      def test2():
          from sigonleton import s1 as s2
          print(s2)
      
      test()
      test2()
      from sigonleton import s1
      from sigonleton import Sql
      s2=Sql(3306,'192.168.1.1')
      print(s1)
      print(s2)
      
      # 被调用的 sigonleton.py文件
      def test():
          from sigonleton import s1
          print(s1.port)
          print(s1)
      def test2():
          from sigonleton import s1 as s2
          print(s2)
      
      test()
      test2()
      from sigonleton import s1
      from sigonleton import Sql
      s2=Sql(3306,'192.168.1.1')
      print(s1)
      print(s2)
      
  • 相关阅读:
    常见英语缩写Abbreviations
    Outlook2016邮件如何设置靠右的预览窗格/Reading Pane?
    Power BI Server的SharePoint Credentials设置,OAuth2 + None
    Power BI 怎么定时同步自己电脑上的数据,并在Power BI server上定时刷新报表?
    Black Unique 全球购骑士卡 吃喝玩乐全有折扣
    怎么导出、同步OneNote上面的笔记到另一台电脑的解决方案
    Spring Cloud Gateway 网关内置API
    Spring Cloud Gateway 过滤器
    Spring Cloud Gateway 路由谓词工厂
    Spring Cloud Gateway 路由定位器
  • 原文地址:https://www.cnblogs.com/foreversun92/p/11462013.html
Copyright © 2011-2022 走看看