zoukankan      html  css  js  c++  java
  • 八、元类

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

    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__)
  • 相关阅读:
    第十八篇:在SOUI中实现PreTranslateMessage
    第十七篇:使用窗口的cache属性加速SOUI的渲染
    通过驱动向打印机发送一段(ESC)控制指令
    转一个希尔排序
    关于Memo或者Edit之类控件, 直接设置Text无法撤销的解决方案
    关于创建无窗体程序的一点心得
    在Vista或更高版本Windows系统中, 获取超大图标的办法
    随笔里的标签为啥不能用空格分隔??
    一个ICMP单元
    Delphi XE5 与其他版本共存
  • 原文地址:https://www.cnblogs.com/zhangjx2457/p/14128065.html
Copyright © 2011-2022 走看看