zoukankan      html  css  js  c++  java
  • 面向对象

    1.元类介绍:
    1.储备知识exec()
    参数1;字符串形式得命令
    参数2.全局作用域(字典形式),如果不指定默认就使用globals()
    参数3.局部作用域(字典形式),如果不指定默认就使用locals()

    2.python 一切皆对象 ,对象可以怎么用?
    2.1. 都可以被引用 x=obj
    2.2. 都可以当作函数得参数传入
    2.3. 都可以当作函数得返回值
    2.4. 都可以当作容器类得元素 li=[func,time]

    # 类也是对象,Foo=type() 类是属于type() 类

    3.什么叫元类
    类得类就叫元类 type type(Foo) == <class 'type'>
    产生类得类称之为元类,默认所有用class定义得类,他们得元类是type
    元类(type) --> 实例化 --> 类(class)--> 实例化 --> 对象

    4.定义类得两种方式:
    4.1 class 关键字得方式 class Chinese:
    4.2 type 元类 定义类得三要素:类名,类的基类们,类得名称空间
    Chinese1=type(class_name,class_bases,class_dic)
     1 # print(globals())
     2 # print(locals())
     3 
     4 # g={
     5 #     'x':1,
     6 #     'y':2
     7 # }
     8 # l={}
     9 # exec("""
    10 # global x,m
    11 # x=10
    12 # m=100
    13 #
    14 # z=3
    15 # """,g,l)
    16 # # print(g)
    17 # print(l)
    18 
    19 # ----------------------------------------------------------
    20 # 类也是对象,Foo=type()
    21 # class Foo:
    22 #     pass
    23 #
    24 # obj=Foo()
    25 # print(type)
    26 # print(type(Foo))
    27 # print(type(obj))
    28 
    29 # class Bar:
    30 #     pass
    31 # print(type(Bar))
    32 
    33 # ----------------------------------------------------------
    34 # 产生类得第一种方式: class
    35 class Chinese:   # Chinese=type(...)
    36     country='China'
    37 
    38     def __init__(self,name,age):
    39         self.name=name
    40         self.age=age
    41 
    42     def talk(self):
    43         print('%s is talking'%self.name)
    44 
    45 
    46 # print(Chinese)
    47 obj=Chinese('alice',12)
    48 print(obj,obj.name,obj.age)
    49 
    50 # 产生类得第二种方式: type
    51 # 定义类得三要素:类名,类的基类们,类得名称空间
    52 class_name='Chinese'
    53 class_bases=(object,)
    54 class_body="""
    55 country='China'
    56 
    57 def __init__(self,name,age):
    58     self.name=name
    59     self.age=age
    60 
    61 def talk(self):
    62     print('%s is talking'%self.name)
    63 """
    64 class_dic={}
    65 exec(class_body,globals(),class_dic)
    66 # print(class_dic)
    67 
    68 Chinese1=type(class_name,class_bases,class_dic)  # 实例化了元类 得到了一个 元类得对象
    69 # print(Chinese.__dict__)
    70 # print(Chinese1)
    71 obj1=Chinese1('alice',18)
    72 print(obj1,obj1.name,obj1.age)
    2.自定义元类控制类的行为
    自定义元类 来控制 类的行为 控制类的创建行为
     1 class Mymeta(type):
     2     def __init__(self,class_name,class_bases,class_dic):
     3         if not class_name.istitle():
     4             raise TypeError('类名的首字母必须大写')
     5         if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
     6             raise TypeError('必须有注释,且注释不能为空!')
     7         print(class_name)
     8         print(class_bases)
     9         print(class_dic)
    10         super(Mymeta,self).__init__(class_name,class_bases,class_dic)
    11 
    12 
    13 class Chinese(object,metaclass=Mymeta):
    14     '''
    15     中文人的类
    16     '''
    17     country='China'
    18 
    19     def __init__(self,name,age):
    20         self.name=name
    21         self.age=age
    22 
    23     def talk(self):
    24         print('%s is talking'%self.name)
    25 
    26 # Chinese=Mymeta(class_name,class_bases,class_dir)
    3.自定义元类控制类的实例化行为
    知识储备 __call__方法
    obj(1,2,3,a=1,b=2,c=3) # 对象在调用时 会触发 __call__
    ------------------------------------
    #生成对象步骤 --》 #1.先造空对象 2.初始化 3.返回值
    def __call__(self, *args, **kwargs): 在元类的__call__()方法中实现
    # 1.先造一个空对象
    obj=object.__new__(self)
    # 2.初始化obj
    self.__init__(obj,*args,**kwargs)
    # 3.返回obj
    return obj

    总结:元类
    __init__ 控制类的创建
    __call__ 控制类的实例化
     1 # class Foo:  #(元类 ype )
     2 #     def __call__(self, *args, **kwargs):
     3 #         print(self)
     4 #         print(args)
     5 #         print(kwargs)
     6 # obj=Foo()
     7 # obj(1,2,3,a=1,b=2,c=3)  # 对象在调用时 会触发 __call__   #obj.__call__(obj,1,2,3,a=1,b=2,c=3)
     8 
     9 # 得出结论是:元类内部也应该有一个 __call__方法 会在调用Foo时触发执行
    10 # Foo(1,2,x=1) 触发 # Foo.__call__(Foo,1,2,x=1) 控制类的调用
    11 # 所以:元类里有__call__() 控制类的实例化(产生对象)
    12 
    13 # ----------------------------------------------------------
    14 class Mymeta(type):                                                       #元类
    15     def __init__(self,class_name,class_bases,class_dic):                  # 控制类的创建
    16         if not class_name.istitle():
    17             raise TypeError('类名的首字母必须大写')
    18         if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
    19             raise TypeError('必须有注释,且注释不能为空!')
    20         # print(class_name)
    21         # print(class_bases)
    22         # print(class_dic)
    23         super(Mymeta,self).__init__(class_name,class_bases,class_dic)
    24 
    25     def __call__(self, *args, **kwargs): #obj=Chinese('alice',age=18)      #控制类的实例化
    26         # print(self)    # <class '__main__.Chinese'>
    27         # print(args)    #('alice',)
    28         # print(kwargs)  #{'age': 18}
    29         # 1.先造一个空对象
    30         obj=object.__new__(self)
    31         # 2.初始化obj
    32         self.__init__(obj,*args,**kwargs)
    33         # 3.返回obj
    34         return obj
    35 
    36 
    37 class Chinese(object,metaclass=Mymeta):
    38     '''
    39     中文人的类
    40     '''
    41     country='China'
    42 
    43     def __init__(self,name,age):
    44         self.name=name
    45         self.age=age
    46 
    47     def talk(self):
    48         print('%s is talking'%self.name)
    49 
    50 obj=Chinese('alice',age=18) # 触发Chinese.__call__(Chinese,'alice',18)
    51 #生成对象步骤 --》 #1.先造空对象 2.初始化 3.返回值
    52 print(obj.__dict__)
    4.自定义元类控制类的实例化行为的应用
    单例模式: 对象的参数都一样 实质就是一个对象 不要在申请新的内容空间 直接使用一个 就是单例模式
    eg: 单例模式对id的应用 obj1 和 obj2 公用一块内存 “优化策略”
    >>> obj1=int(1)
    >>> obj2=int(1)
    >>> obj1 is obj2
    True
    >>> id(obj1)
    1897295328
    >>> id(obj2)
    1897295328
    --------------------------------
    自己定义的类 对象内部的特征如果是一样的就公用一块内存 用单例模式呢:
    实现单例模式 是一种 优化策略 多个对象公用一块内存
    __instance=None #__instance=obj1
    def singleton(cls):
    print(obj1 is obj2)
    -------------------------------
    单例模式的实现方式:1.@classmethod def singleton(cls):
    2.利用元类实现
     1 # 单例模式:
     2 # 实现方式一:
     3 # class MySQL:
     4 #     __instance=None  #__instance=obj1
     5 #     def __init__(self):
     6 #         self.host='127.0.0.1'
     7 #         self.port=3306
     8 #
     9 #     @classmethod
    10 #     def singleton(cls):
    11 #         if not cls.__instance:
    12 #             obj=cls()
    13 #             cls.__instance=obj
    14 #         return cls.__instance
    15 #
    16 #
    17 #     def conn(self):
    18 #         pass
    19 #
    20 #     def execute(self):
    21 #         pass
    22 #
    23 # # obj1=MySQL()
    24 # # obj2=MySQL()
    25 # #
    26 # # print(obj1)
    27 # # print(obj2)
    28 #
    29 # obj1=MySQL.singleton()
    30 # obj2=MySQL.singleton()
    31 #
    32 # print(obj1.host)
    33 # print(obj2)
    34 # print(obj1 is obj2)
    35 
    36 # --------------------------------------------------------
    37 # 实现方式二:通过元类  实现了单例模式
    38 class Mymeta(type):
    39     def __init__(self,class_name,class_bases,class_dic):    #控制类的创建
    40         if not class_name.istitle():
    41             raise TypeError('类名的首字母必须大写')
    42         if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
    43             raise TypeError('必须有注释,且注释不能为空!')
    44         super(Mymeta,self).__init__(class_name,class_bases,class_dic)
    45         self.__instance=None
    46 
    47     def __call__(self, *args, **kwargs):   #控制类的实例化
    48         if not self.__instance:
    49             obj=object.__new__(self)
    50             self.__init__(obj)
    51             self.__instance=obj
    52         return self.__instance
    53 
    54 
    55 
    56 class Mysql(object,metaclass=Mymeta):
    57     '''
    58     类的单例模式
    59     '''
    60     def __init__(self):
    61         self.host='127.0.0.1'
    62         self.port=3306
    63 
    64     def conn(self):
    65         pass
    66 
    67     def execute(self):
    68         pass
    69 
    70 obj1=Mysql()  # 在这个对象(Mysql)的类里面调用__call_()方法
    71 obj2=Mysql()
    72 obj3=Mysql()
    73 
    74 print(obj1 is obj2 is obj3)


  • 相关阅读:
    el-checkbox-group设置每行固定数量(左对齐)
    jsonObject.toJSONString()将数
    aspose bookmark _GoBack
    HttpMessageNotReadableException: Required request body is missing:
    vs2019快捷键
    gitlab 汉化
    sql server in vs exists
    win10彻底解决时间同步不一致的问题
    how to cracked office2019
    直接从官网下载Windows 10 ISO文件
  • 原文地址:https://www.cnblogs.com/alice-bj/p/8541231.html
Copyright © 2011-2022 走看看