• 元类 metaclass


    一个类没有声明自己的元类,默认他的元类就是type,除了使用内置元类type,

    我们也可以通过继承type来自定义元类,然后使用metaclass关键字参数为一个类指定元类

    自定义元类可以控制类的产生过程,类的产生过程其实就是元类的调用过程

    # 1、类名class_name=''
    #
    # 2、基类们class_bases=(object,)
    #
    # 3、类的名称空间class_dic,类的名称空间是执行类体代码而得到的
    #
    # 调用type时会依次传入以上三个参数
    
    class Mymeta(type):
        def __init__(self,class_name,class_bases,class_dic):
            super(Mymeta,self).__init__(class_name,class_bases,class_dic)
            if class_name.islower():
                raise TypeError("leiming %s"%class_name)
            if '__doc__'not in class_dic or len(class_dic['__doc__'].strip('
    '))==0:
                raise TypeError("xu han you zhu shi")
    
    class Myclass(object,metaclass=Mymeta):
        """__doc__"""
        nickname='wes'
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def say(self):
            print('%s say hello'%self.name)
    m1=Myclass('haha',20)
    m1.say()
    # # 1、类名class_name=''
    # #
    # # 2、基类们class_bases=(object,)
    # #
    # # 3、类的名称空间class_dic,类的名称空间是执行类体代码而得到的
    # #
    # # 调用type时会依次传入以上三个参数
    #
    class Mymeta(type):
        def __init__(self,class_name,class_bases,class_dic):
            super(Mymeta,self).__init__(class_name,class_bases,class_dic)
            if class_name.islower():
                raise TypeError("leiming %s"%class_name)
            if '__doc__'not in class_dic or len(class_dic['__doc__'].strip('
    '))==0:
                raise TypeError("xu han you zhu shi")
        # def __call__(cls,*args,**kwargs):
        #     print(cls)
        #     print(args)
        #     print(kwargs)
        #     return 123
        def __call__(self, *args, **kwargs):          #默认正常的
            obj=self.__new__(self)                   #先new 一个空对像
            self.__init__(obj,*args,**kwargs)       #初始化obj,self 是Myclass,即myclass 的初始化函数
            return obj                              #返回初始化ok的对象
    
    class Myclass(object,metaclass=Mymeta):
        """__doc__"""
        nickname='wes'
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def say(self):
            print('%s say hello'%self.name)
    m1=Myclass('haha',20) #调用对象Myclass类的__call__
    # m1.say()
    print(m1)
    # 调用一个对象,就是触发对象所在类中的__call__方法的执行,
    # 如果把OldboyTeacher也当做一个对象,那么在OldboyTeacher
    # 这个对象的类中也必然存在一个__call__方法
    Host='127.0.0.1'
    Port=3306
    class Mymeta(type):
        def __init__(self,name,bases,dic):   #定义Mysql时触发
            super(Mymeta,self).__init__(name,bases,dic)
            # self.__instance=super(Mymeta,self).__call__(Host,Port)  #产生一个默认的实例
            #or
            self.__instance=self.__new__(self)
            self.__init__(self.__instance,Host,Port)  #固定了agrs kwargs,所以初始化为同一个对象即单例
        def __call__(self, *args, **kwargs):     #产生Mysql对象时触发,所有对象从这里来
            if args or kwargs:             #用户输入的自定义args,kwargs
                obj=self.__new__(self)     #空对象
                self.__init__(obj,*args,**kwargs) #self 是Mysql 类(对象)
                return obj     #返回自定义的对象
            return self.__instance   #返回默认的对象
        
    class Mysql(object,metaclass=Mymeta):
        def __init__(self,host,port):
            self.host=host
            self.port=port
    obj1=Mysql()
    print(obj1.__dict__,id(obj1))
    obj2=Mysql()
    print(obj2.__dict__,id(obj2))
    # {'host': '127.0.0.1', 'port': 3306} 7884304
    # {'host': '127.0.0.1', 'port': 3306} 7884304
    obj=Mysql('127.1.1.1',3305)
    print(obj.__dict__,id(obj))

    {'host': '127.0.0.1', 'port': 3306} 34885136
    {'host': '127.0.0.1', 'port': 3306} 34885136

    单例:即单个实例,指的是同一个类实例化多次的结果指向同一个对象,用于节省内存空间


    {'host': '127.1.1.1', 'port': 3305} 34885200

    Host='127.0.0.1'
    Port=3306
    def Singleton(cls):
        cls_instance=cls(Host,Port) #初始化一个固定的
        def wrapper(*args,**kwargs):    
            if args or kwargs:
                obj=cls(*args,**kwargs)   #初始化自定义的
                return obj
            return cls_instance
        return wrapper
    @Singleton              #修饰符实现
    class Mysql():
        def __init__(self,host,port):
            self.host=host
            self.port=port
    obj1=Mysql()
    obj2=Mysql()
    print(obj1.__dict__,obj2.__dict__)
    obj3=Mysql('127.7l7..7.',3309)
    print(obj3.__dict__)

    {'host': '127.0.0.1', 'port': 3306} {'host': '127.0.0.1', 'port': 3306}
    {'host': '127.7l7..7.', 'port': 3309}



  • 相关阅读:
    ASP.NET MVC 重点教程一周年版 第二回 UrlRouting
    ASP.NET MVC 重点教程一周年版 第三回 Controller与View
    DynamicData for Asp.net Mvc留言本实例 下篇 更新
    Asp.net MVC视频教程 18 单选与复选框
    使用ASP.NET MVC Futures 中的异步Action
    ASP.NET MVC RC 升级要注意的几点
    ATL、MFC、WTL CString 的今生前世
    msvcprt.lib(MSVCP90.dll) : error LNK2005:已经在libcpmtd.lib(xmutex.obj) 中定义
    关于Windows内存的一些参考文章
    Windows访问令牌相关使用方法
  • 原文地址:https://www.cnblogs.com/wuxi9864/p/10003791.html
Copyright © 2020-2023  润新知