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)

 

posted @ 2018-07-02 22:03  Marcki  阅读(188)  评论(0编辑  收藏  举报