• 八、元类


    一、需要了解的属性和方法

    1.__bases__

    是一个元祖,里面是继承的类

    class A(object):
        pass
    
    class B(object):
        pass
    
    class Myclass(A,B):
        pass
    
    if __name__=="__main__":
        print(Mycalss.__bases__)   #(<class '__main__A'>,<calss '__main__B'>)

    2.__dict__

    把属性信息放在字典里输出

    class MyClass(object):  # MyClass 是类 , 类 其实就是 定义如何创建对象的一段代码
        a = 0  # 类变量 (归属于类)
    
        def __init__(self, name, age):
            temp = 1  # 局部变量
            self.name = name  # self  是对象
            self.age = age  # name ,age  实例变量(归属于对象)
    
        def get_name(self):
            return self.name
    
    
    if __name__ == '__main__':
        obj = MyClass('zjx', 18)
        print(MyClass.__dict__)  
        print(obj.__dict__)  # {'name':'zjx','age':'18'}

    3.__setattr__

    __setattr__:设置属性

    __delattr__:删除属性

    class MyClass(object):
        def __init__(self, name):
            self.name = name
    
        def __setattr__(self, key, value):
            print("setattr is running ....")
            super().__setattr__(key, value)
    
        def __delattr__(self, item):
            print("delattr is running ...")
            if item == 'name':
                # raise AttributeError('name 属性不允许删除')
                pass
            else:
                super().__delattr__(item)
    
    
    if __name__ == '__main__':
        obj = MyClass('zhang')
        obj.name = 'li'
        del obj.name
        print(obj.name)
        
    '''
    setattr is running ....
    setattr is running ....
    delattr is running ...
    '''

    4.__slots__

    覆盖 __dict__中的属性 , 限制 对象有哪些属性,如下举例,限制属性只有age name,没有x属性

    应用场景:创建大量对象,可以用 __slots__ 指定对象属性,减少内存

    # 节省内存
    
    class MyClass(object):
        __slots__ = ['age','name']  # 覆盖 __dict__中的属性 , 限制 对象有哪些属性
        # 应用场景:创建大量对象,可以用 __slots__ 指定对象属性,减少内存
    
        def __init__(self, name,x):
            self.name = name
    
    if __name__ == '__main__':
        obj = MyClass('aaaa',1)
        obj2 = MyClass('bbb',1)
        print(obj.__slots__)
        print(MyClass.__dict__)

    二、元类基础

    类 :定义如何创建对象 ( 对象有哪些属性,有哪些方法),抽象的

    • 笔记本类 :属性:大小、颜色;方法:开机、关机等

    • 英雄:属性:名字、生命值、魔抗;方法:技能1、技能2 ...

    对象:类的实例化,真实存在的,具体的

    • MacBookPro 2020 指定的型号 ,真实存在的东西

    • 无极剑圣 、奥特曼, 真实的英雄

    对象的类型是什么?

    • 无极剑圣的类型是什么呢?(英雄)

    • MacBookPro 2020 的类型是什么(笔记本)

    类的继承:用代码模拟现实中的类

    • 哺乳动物 -> (人、牛、羊) -> (学生、老师)

    类的类型是什么?(元类)

    • print(type(1)) # int

    • print(type(int)) # type

    对象(zhansan)是有 它对应的类(Student)创建的

    类是由什么创建的?-----元类

    元类创建类,类创建对象

    元类不仅可以创建类,也可以创建他自己。元类是最顶层的了

    print(type(type))  # type

    三、如何使用元类创建类 

    class MyClass(object):
        pass
    
    
    def __init__(self, name):
        self.name = name
    
    
    def study():
        pass
    
    
    def hello(self):
        print(f'Hi,my name is {self.name}!')
    
    
    class A(object):
        pass
    
    
    # 所有类都是type创建的对象
    Student = type('Student', (A,), {
        '__init__': __init__,
        'say': hello,
    })
    
    if __name__ == '__main__':
        # 使用类创建对象
        obj = MyClass()
        # 如何使用元类创建类?
        xiaoming = Student('小明')  # int  list ... 都是都由元类创建
        print(xiaoming.name)
        xiaoming.say()
    
    print(type(object))  # object 也是有type创建的1
    print(type(Student))

    四、如何优雅的创建元类 

    class MyMetaclass(type):
    
        def hi(self):
            print('hi')
    
        def __new__(cls, name, bases: tuple, attrs):
            # __new__ 创建对象
            """
            创建对象(这个对象是一个类)
            :param name: 字符串,类的名称
            :param x: 元组(基础类1,基础类2.....)
            :param attrs: 字典(__dict__属性)
            """
            name = 'Person'
            attrs['name'] = '某人'
            attrs['age'] = 18
            attrs['hi'] = cls.hi
            attrs['add'] = lambda self, a, b: a + b
            bases = (object,)
            return super().__new__(cls, name, bases, attrs)  # 固定返回
    
    
    # metaclass : 指定类是由谁创建的
    # 所有类,如果不指定metaclass,默认metaclass是type
    # 自定义某个元类,通常是从type继承,为了改变如何创建类
    
    class MyClass(object, metaclass=MyMetaclass):
        pass
    
    
    if __name__ == '__main__':
        print(MyClass.__dict__)
        print(MyClass.__name__)
        print(MyClass.__bases__)
  • 相关阅读:
    SpringMvc 框架
    面试:你最大的长处和弱点分别是什么?这些长处和弱点对你在企业的业绩会有什么样的影响?
    线程、并发、并行、进程是什么,以及如何开启新的线程?
    面向对象三大特性
    一台客户端有三百个客户与三百个客户端有三百个客户对服务器施压,有什么区别?
    JavaScript 引擎
    Spring Data JPA简介 Spring Data JPA特点
    redo log 有什么作用?
    Spring的简介和优点?
    学习笔记——享元模式Flyweight
  • 原文地址:https://www.cnblogs.com/zhangjx2457/p/14128065.html
Copyright © 2020-2023  润新知