zoukankan      html  css  js  c++  java
  • 元类

    元类

    python中一切皆对象,其类也是对象

    对象的要求或者意义:

    • 可以被引用,例如:x=obj
    • 可以当作函数进行参数传入
    • 可以作为容器类的元素
    • 可以当作函数的返回值

    1.元类的含义:产生类的类称之为元类,默认所有用class定义的类,他们的元类都是type

    python中运用关键字class定义类的过程是:class(A)  其实就是 type实例化出来的,之后再由类实例化产生对象

    2.定义类的两种形式

    通过class关键字:class(Chinese) : #Chinese = type(...)

    通过type: 定义出类的三要素:类的名称,类的基类,类的名称空间

    3.自定义元类的应用

    3.1可以控制类的具体行为

    通过def __init__(self,class_name,class_bases,class_dic),获取到类的名称,类的基类,类的名称空间

    之后运用class Chinese(object,metaclass=Mymeta) ,利用元类中的__init__来进行控制类名,类体的操作

    def __init__(self,class_name,class_bases,class_dic):
         if not class_name.istitle():
              raise TypeError('类名的首字母必须大写')

    3.2可以控制类的实例化过程

    通过def __call__(self,*args,**kwargs):进而得到对象的属性,

    之后在进行三步操作:

    • 创建空对象
    • 初始化对象
    • 返回对象值
        def __call__(self, *args, **kwargs): #Chinese('egon',age=18)
            # print(self) #self=Chinese
            # print(args) #args=('egon',)
            # print(kwargs) #kwargs={'age':18}
    
            #第一件事: 造出一个空对象obj
            obj=object.__new__(self)
            #第二件事: 初始化obj
            self.__init__(obj,*args,**kwargs)
            #第三件事: 返回obj
            return obj

    4.单例模式

    运用python实现单例模式有两种方法:

    1.定义一个绑定类的绑定方法

    class MySQL:
        __instance = None
    
        def __init__(self):
            self.host='127.0.0.1'
            self.port=3306
    
        @classmethod
        def singleton(cls):
            if not cls.__instance:
                obj = cls()
                cls.__instance=obj
            return cls.__instance

    2.通过元类中的内置方法__call__来实现

    class Mymeta(type):
        def __init__(self,class_name,class_bases,class_dic):
    
    
            super(Mymeta,self).__init__(class_name,class_bases,class_dic)
            self.__instance=None
    
        def __call__(self, *args, **kwargs): #Chinese('egon',age=18)
            if not self.__instance:
                obj=object.__new__(self)
                self.__init__(obj)
                self.__instance=obj
    
            return self.__instance
    # class Foo:
    #     pass
    # f=Foo()
    # print(type(f))
    # print(type(Foo))
    
    # g={'x':1,'y':2}
    # l={}
    # exec("""
    # global x,m
    # x=10
    # m=100
    # z=3
    # """,g,l)
    # print(g)
    # print(l)
    # -------------------------
    # 产生类得第一种方式:
    class Chinese:
        country='China'
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
        def talk(self):
            print('%s is talking'%self.name)
    
    # obj=Chinese('alice',12)
    # obj.talk()
    # print(obj.name,obj.age)
    
    #产生类得第二种方式:
    class_name='Chinese'
    class_base=(object,)
    class_body="""
    country='China'
    def __init__(self,name,age):
        self.name=name
        self.age=age
    
    def talk(self):
        print('%s is talking'%self.name)
    """
    # class_dic={}
    # exec(class_body,globals(),class_dic)
    # # print(class_dic)
    # ch = type(class_name,class_base,class_dic)
    # obj1=ch('alice',12)
    # print(obj1.__dict__)
    # print(ch.__dict__)
    # print(ch)
    # print(obj1,obj1.name,obj1.age)
    
    #自定义元类 控制类的行为:
    class Mymeta(type):  #元类
        # print('--1--')
        def __init__(self,class_name,class_bases,class_dic):   # 控制类的创建
            # print(class_name)
            # print(class_bases)
            # print(class_dic)
            if not class_name.istitle():
                raise TypeError('类名的首字母必须大写')
            if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
                raise TypeError('必须有注释,且注释不能为空')
    
            super(Mymeta, self).__init__(class_name,class_bases,class_dic)
    
        def __call__(self, *args, **kwargs):  # 控制类的实例化
            # print(self)
            # print(args)
            # print(kwargs)
            obj=object.__new__(self)           #1.造空对象
            self.__init__(obj,*args,**kwargs)  #2.初始化obj
            return obj                        #返回obj
    
    
    class Chinese(object,metaclass=Mymeta):
        '''
        中文人的类
        '''
        country='China'
        def __init__(self,name,age):
            print('--2--')
            self.name=name
            self.age=age
    
        def talk(self):
            print('%s is talking'%self.name)
    
        def __call__(self, *args, **kwargs):
            print(self)
            print(args)
            print(kwargs)
    
    
    # obj=Chinese('alice',12)   # 触发它的类的 __call__() 元类
    # obj(1,2,3,a=1,b=2)    # 触发它的类的 __call__()  Chinese
    # print(obj.__dict__)
    # print(Chinese.__dict__)
    #
    # print(type(Chinese))
    # Chinese=Mymeta(class_name,class_bases,class_dir)
    # print(obj.__dict__)
    
    #自定义元类的应用:
    
    # obj1=int(1)
    # obj2=int(1)
    # print(id(obj1))
    # print(id(obj2))
    # print(obj1 is obj2)  # 实现了单例模式 参数相同 多个对象 使用同一块内存 是一种优化策略
    
    # 单例模式 实现方式一:
    
    class Mymeta(type):
        def __init__(self,class_name,class_bases,class_dic):
            super().__init__(class_name,class_bases,class_dic)
            self.__instance=None
    
        def __call__(self, *args, **kwargs):
            if not self.__instance:
                obj = object.__new__(self)
                self.__init__(obj)
                self.__instance=obj
            return self.__instance
    
    
    
    class Mysql(object,metaclass=Mymeta):
        # __instance=None
        def __init__(self):
            self.host='127.0.0.1'
            self.port=3306
    
        # @classmethod
        # def singleton(cls):
        #     if not cls.__instance:
        #         obj=cls()
        #         cls.__instance=obj
        #     return cls.__instance
    
        def conn(self):
            pass
    
        def execute(self):
            pass
    
    # obj1=Mysql()
    # obj2=Mysql()
    # print(obj2.__dict__)
    # print(id(obj1))
    # print(id(obj2))
    
    # obj1=Mysql.singleton()
    # obj2=Mysql.singleton()
    # # print(obj1.__dict__)
    # print(id(obj1))
    # print(id(obj2))
    
    # obj1=Mysql()
    # obj2=Mysql()
    # print(id(obj1))
    # print(id(obj2))
    

     

  • 相关阅读:
    Appium介绍
    selenium2支持无界面操作(HtmlUnit和PhantomJs)
    selenium让人摸不着头脑的问题
    页面加载时间过长
    Selenium Test 自动化测试 入门级学习笔记
    Selenium 2.0 WebDriver 自动化测试 使用教程 实例教程 API快速参考
    Selenium执行测试脚本稳定性的一些经验分享交流
    怎么等待页面元素加载完成
    如何智能的等待页面加载完成
    filezilla安装
  • 原文地址:https://www.cnblogs.com/Mryang123/p/8620740.html
Copyright © 2011-2022 走看看