• 昨日回顾


    #type只传一个参数有什么用?
    #打印对象的类型
    # print(type(1))
    #class 底层原理,通过type类来实例化得到类
    # def __init__(self,name):
    #     self.name=name
    # Person=type('Person',(object,),{'x':1,'__init__':__init__})
    # p=Person('lqz')
    # print(Person.__dict__)
    # print(p.__dict__)
    # print(p.x)
    #等同于
    # class Person(object):
    #     x=1
    #     def __init__(self, name):
    #         self.name = name
    # p=Person('lqz')
    # print(Person.__dict__)
    # print(p.__dict__)
    # print(p.x)
    
    
    #exec  执行字符串的代码,当成python解释器
    
    # ss='''
    # x=1
    # print(x)
    # '''
    # g={}
    # l={}
    # exec(ss,g,l)
    # print(l)
    
    
    #自定义元类:继承type
    # class Mymeta(type):
    #     def __init__(self,name,bases,dic):
    #         #self 是Person 这个类(对象)
    #         #在这个位置,其实self也就说Person这个类,内部已经有东西了,名称空间已经有东西了
    #         #所以在这个地方,可以通过dic来判断名称空间
    #         #也可以直接通过self.__dict__/self.属性 来判断
    #         a=dic.get('name')
    #         if not a :
    #             raise Exception('没有name属性,不能创建')
    #     # def __call__(self, *args, **kwargs):
    #     #     pass
    #
    # class Person(metaclass=Mymeta):  #Person=Mymeta('Person',(object,),{...}) Mymeta类实例化,会把三个参数传到Mymeta的__init__方法中
    # # class Person():  #Person=Mymeta('Person',(object,),{...}) Mymeta类实例化,会把三个参数传到Mymeta的__init__方法中
    #     def __init__(self,name):
    #         self.name=name
    #         raise Exception('就不让你创建')
    #
    #
    # p=Person('lqz')  #自动触发Person类__init__的执行
    #总结:可以通过自定义元类,重写__init__方法来控制类的产生
    
    
    # 通过元类控制类的调用过程,实例化产生对象的过程
    
    
    # class Mymeta(type):
    #     def __call__(self, *args, **kwargs):
    #         #该方法必须返回一个对象(类对象),这个地方返回什么 p=Person('lqz') p就是什么
    #         #返回一个真正的Person类的对象
    #         #第一步:产生一个空对象
    #         #object.__new__(self)  传一个参数,传类,就会产生一个该类的空对象
    #         #obj是Person类的空对象
    #         obj=object.__new__(self)
    #         # print(self.__new__ is object.__new__)  # True
    #
    #         #第二步:初始化该对象,把初始值放到对象中
    #         #obj是Person类的空对象  obj.__init__  调用自己的绑定方法,也就说Person类中写的__init__方法
    #         obj.__init__(*args, **kwargs)
    #         #还可以类来调用
    #         # Person.__init__(obj,*args, **kwargs)
    #         # self.__init__(obj,*args, **kwargs)
    #         # print(obj.name)
    #         #第三步:把该对象返回
    #         return obj
    #
    # class Person(metaclass=Mymeta):
    # # class Person():
    #     def __init__(self,name):
    #         self.name=name
    #     def __call__(self, *args, **kwargs):
    #         print('xxx')
    #
    #
    # p=Person('lqz')
    # print(p.name)
    # print(p)
    # # 原来的理解Person('lqz') 会调用Person类的__init__的方法
    # # 这个位置会调用元类的__call__方法,所以在__call__方法中调用了Person  __init__方法,来完成对象的初始化
    # p()
    
    
    #模板:控制对象的产生
    # class Mymeta(type):
    #     def __call__(self, *args, **kwargs):
    #         obj=object.__new__(self)
    #         obj.__init__(*args, **kwargs)
    #         return obj
    #
    # class Person(metaclass=Mymeta):
    #     def __init__(self,name):
    #         self.name=name
    #     def __call__(self, *args, **kwargs):
    #         print('xxx')
    #
    # p=Person('lqz')
    
    
    
    
    #昨天的作业
    # class Mymeta(type):
    #     def __call__(self, name,age):
    #         # print(name)
    #         # print(age)
    #         obj=object.__new__(self)
    #         # obj.__init__(name,age)
    #         # obj.name=name
    #         # obj.age=age
    #         obj.__dict__['attr']={'name':name,'age':age}
    #         return obj
    #
    # class Person(metaclass=Mymeta):
    #     def __init__(self,name,age):
    #         self.name=name
    #         self.age=age
    #
    # p=Person('lqz',18)
    # print(p.__dict__)
    # print(p.attr['name'])
    
    #不用init方法,但是能完成对象的初始化
    
    
    
    #赠送元类
    
    # object.__new__
    
    # class Person():
    #     def __init__(self,name,age):
    #         print('__init__')
    #         self.name=name
    #         self.age=age
    #     def __new__(cls, *args, **kwargs):
    #         print('__new__')
    #         #生成一个Person类的空对象
    #         return object.__new__(cls)
    
    # p=Person('lqz',19)
    # print(p)
    
    #object.__new__ 传哪个类就得到哪个类的空对象
    # p=object.__new__(Person)
    # print(p)
    
    #__new__和__init__的区别
    #__new__ 创建空对象
    #__init__ 初始化空对象
    
    #object.__new__(Person)    :生成Person类的对象  空的
    #type.__new__(cls,name,bases,dic)  :生了cls这个类对象,里面有东西
    #元类中
    #__init__:控制类的产生,在__new__之后
    #__call__:对着对象的产生
    #__new__:控制类产生最根上,其实本质最根上也不是它,是type的__call__,但是我们控制不了了
    #
    class Mymeta(type):
        def __init__(self,name,bases,dic):
            #self 是Person类,Person类中有名称空间之类的了
            # print('xxxxxxx')
            # print(args)
            # print(kwargs)
            # print(name)
            # print(bases)
            # print(dic)
            pass
            # self.name='xxxxxxx'
        def __new__(cls, name,bases,dic):
            # print(name)
            # print(bases)
            # print(dic)
            #产生空对象(空类),在这里面生成的并不是空类,是有数据的类了
            #如何完成类的初始化,并且把name,bases,dic这些东西放入
            # return type.__new__(cls,name,bases,dic)
            dic2={'attr':{}}
            for k,v in dic.items():
                #加入这一句,类名称空间中带__的就不会放到attr中
                if not k.startswith('__'):
                    dic2['attr'][k]=v
            print('-------',dic2)
            return type.__new__(cls,name,bases,dic2)
    
    
    class Person(metaclass=Mymeta):     # Person=Mymeta(name,bases,dic)   调用type的__call__,内部调用了Mymeta.__new__,又掉Mymeta的__init__
        school='oldboy'
        age=10
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
    
    print(Person.__dict__)
    print(Person.attr['school'])
    # p=Person('nick',18)
    
  • 相关阅读:
    vim使用技巧
    排序
    2020-3-27 学习面向对象的笔记
    小圆圈第三章答案
    内置函数部分用法
    Pycharm快捷键
    小猿圈第二章答案
    Typora学习笔记
    AI的真实感
    Unity 横版2D移动跳跃问题——关于一段跳与二段跳
  • 原文地址:https://www.cnblogs.com/yushan1/p/11461560.html
Copyright © 2020-2023  润新知