zoukankan      html  css  js  c++  java
  • python之元类高级应用,自定义元类隐藏属性,三种单例模式

    1.自定义元类隐藏对象属性

    class Mmeta(type):

        def __init__(self,class_name,class_bases,class_dic):

                super(Mymeta,self).__init__(self,class_name,class_bases,class_dic)

        def __call__(self,*args,**kwargs):

            obj=self.__new__(self)

            self.__init__(obj,*args,**kwargs)

            obj.__dict__={'_%s__%s'%(self_name,k):v for k,v in obj.__dict__.items()}

            return obj

    class Foo(object,metaclass=Mymeta)

            def __init__(self,name,age)

                    self.name=name

                    self.age

    class Mymeta(type):
        def __init__(self, class_name, class_bases, class_dic):
            # 控制Foo的创建  即类的创建 初始化
            super(Mymeta, self).__init__(class_name, class_bases, class_dic)
    
        def __call__(self, *args, **kwargs):  # 调用对象的自动触发 self=foo   把foo当做对象  python中一切皆对象
            # 控制Foo的调用过程,即Foo对象的产生过程
    
            obj = self.__new__(self)  # self=foo     #新建一个空对象obj
            self.__init__(obj, *args, **kwargs)
            obj.__dict__ = {'_%s__%s' % (self.__name__, k): v for k, v in obj.__dict__.items()}  # 修改对象属性的封装操作__开头
            return obj
    
    
    class Foo(object, metaclass=Mymeta):  # Foo=Mymeta(......)  把foo当做一个对象来看待
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    
    obj = Foo('egon', 18, 'mele')
    print(obj.__dict__)
    
    # 把所有的继承类看做对象,先找对象,object是所有对象的父类  object看做对象的话   type是object元类 最终找的是type
    # 在找自定义类-type             type是所有对象和类的元类
    

    单例模式:基于某种方式实例化多次,得到实例是同一个

    为啥要用:

                当实例化多次得到的对象中存放的属性都一样时,应该将多个对象指向同一个内存地址,即同一个实例。

    1.类中定义

    import setting

    class Mymeta:

        __instacne=None    

          def __init__(self,ip,port)

                self.ip=ip

                self.port=port

        @classmethod

            def form-conf(cls):

                if cls.__instacne is None:

                    cls.__instacne=cls(setting_ip,setting_port)

                return cls.__instacne

    import setting
    
    """
    
    # 1.在类中定义单例模式方法一:
    class Mymeta:
        __instacne = None
    
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
        @classmethod
        def from_conf(cls):  # 类调用读取文件实例化,多次读取相同内容但内存地址不一样#节省内存
            if cls.__instacne is None:  # 判断是否有没有实例化赋值
                cls.__instacne = cls(setting.IP, setting.port)  
            return cls.__instacne
    
    """

    2.装饰器定义法

      def   singleton(cls):

            __instance=cls(setting_ip,setting_port)

            def wrapper (*args,**kwargs):

                   if len(args)==0 and len(kwargs)==0:

                        return __instance

                   return cls(*args,**kwargs)

            return wrapper

    @singleton

    class Mymeta    

        def __init__(self,ip,port)

            self.ip=ip

            self.port=port

    # 装饰器的单例模式方式二
    """
    import setting
    
    
    def singleton(cls): #cls是原始的mysql内存地址
        __instacne = cls(setting.IP, setting.port)   #直接先导入文件实例化
    
        def wrapper(*args, **kwargs):           #wrapper=mysql赋值过后内存地址
            if len(*args) == 0 and len(**kwargs) == 0:#在判断是否用户输入参数
                return __instacne                     #没有是直接返回上面已经实例化的
            return cls(*args, **kwargs)              #用户输入的有参数的话直接实例化一个兵返回
    
        return wrapper
    
    
    @singleton
    class Mysql:            #Mysql=singleton(Mysql) mysql内存地址给cls # singleton(Mysql)= wrapper内存地址     调用mysql是调用warpper                    
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
    
    obj = Mysql()
    obj2 = Mysql()
    obj3 = Mysql()
    
    """

    3.元类定义法

      class Mymeta(type):

            def __init__(self,class_name,class_bases,class_dic)

                super(Mymeta,self).__init__(class_name,class_bases,class_dic)

                self.__instance=self.__new__(self)

                seif.__init__(self,__instance,setting_ip,setting_port)

            def __call__(self,*args,**kwargs):

                   if len(args)==0 and len(kwargs)==0:

                        return   self.__instance

                   obj=self.__new__(self)

                    self.__init__(obj,*args,**kwargs)

                    return obj

    class Mysql(object,metaclass=Mymeta):

            def __init__(self,ip,port)

                    self.ip=ip

                     self.port=port

    # 单例模式方式三
    import setting
    
    
    class Mymeta(type):
        def __init__(self, class_name, class_beses, class_dic):  # 一开始就初始化
            super(Mymeta, self).__init__(class_name, class_beses, class_dic)
            self.__instance = self.__new__(self)  # 造出一个Mysql空对象
            self.__init__(self.__instance, setting.IP, setting.port)  #在配置文件中加载配置完成Mysql对象初始化
    
            #print(self.__instance)
           # print(self.__instance.__dict__)
    
        def __call__(self, *args, **kwargs):  # self=Mysql      #接受用户传值 调用对象自动触发 把Mysql看做对象
            if len(args) == 0 and len(kwargs) == 0:  # 判断有没有传值
                return self.__instance
            obj = self.__new__(self)  # 造出一个空对象
            self.__init__(obj, *args, **kwargs)  # 根据传值参数,初始化对象
            return obj
    
    
    class Mysql(object, metaclass=Mymeta):  # 把Mysql当做一个对象看待 #Mysql=Mymeta(...)调用元类生成mysql对象
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
    
    obj = Mysql()
    obj1 = Mysql()
    obj2 = Mysql()
    obj3 = Mysql('10.10.10.10', 3308)
    print(obj)
    print(obj1)
    print(obj2)
    print(obj3)Mysql看做对象
            if len(args) == 0 and len(kwargs) == 0:  # 判断有没有传值
                return self.__instance
            obj = self.__new__(self)  # 造出一个空对象
            self.__init__(obj, *args, **kwargs)  # 根据传值参数,初始化对象
            return obj
    
    
    class Mysql(object, metaclass=Mymeta):  # 把Mysql当做一个对象看待 #Mysql=Mymeta(...)调用元类生成mysql对象
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
    
    obj = Mysql()
    obj1 = Mysql()
    obj2 = Mysql()
    obj3 = Mysql('10.10.10.10', 3308)
    print(obj)
    print(obj1)
    print(obj2)
    print(obj3)
  • 相关阅读:
    【GIS】Vue、Leaflet、highlightmarker、bouncemarker
    【PHP】xampp配置多个监听端口和不同的网站目录(转)
    【ArcGIS】栅格分析-问题之001(转)
    java登录央行征信网站
    登录中国人民银行征信中心
    爬取百度百科上中国所有城市的信息
    pycharm pro版本激活
    一种爬虫架构分享
    中国联通短信验证码
    中国联通通话记录、身份认证、上网记录等信息
  • 原文地址:https://www.cnblogs.com/Marcki/p/10111938.html
Copyright © 2011-2022 走看看