• python_元类


    一、引导

    class Demo:
        def func(self):
            pass
    
    obj = Demo()
    print(type(obj))  
    print(type(Demo)) # Demo = type()
    
    # 所有你写的类默认情况下都是type产生的
    # 产生的类称之为 元类!! 即type就是元类
    
    # 类的三大特征:
    1.类名
    2.父类
    3.类的名称空间

    eval与exec

    res = """
    print('555')
    """
    res2 = """
    for i in range(5):
        print(i)
    """
    
    eval(res) # 555
    exec(res) # 555
    eval(res2) # 报错
    exec(res2) # 1 2 3 4 5
    
    # 从上面执行的结果可以得知:
    #  eval与exec都可以识别字符串中代码并执行,但是eval不支持逻辑性代码

    二、不依赖class关键字创建类

    如何产生一个类:

    # 上面说类由:类名、父类、类的名称空间组成
    
    class_name = 'User'   # 类名
    class_base = (object,)   # 父类,注意必须是元组,逗号不能忘
    #类的名称空间:类体代码
    res = """
    school = "oldboy"
    def __init__(self):
        self.name = name
    def func():
        pass
    """
    
    class_attrs = {}
    exec(res,{},class_attrs) # 将res执行产生的名称空间放到class_attrs中
    # class_global(中间)一般情况下都为空,除非在字符串代码内部用global关键字声明,才会将产生的名字丢到class_global全局名称空间中
    print(class_attrs)
    # {'school': 'oldboy', '__init__': <function __init__ at 0x0000000001D02EA0>, 'func': <function func at 0x00000000027DDE18>}
    # 调用元类创建自定义类
    User = type(class_name,class_bases,class_attrs) #传参:将类名、父类、类的名称空间丢给type产生 print(User) #<class '__main__.User'>

    # 它可以访问自身的属性和方法,并实例化产生对象 print(User.school) #oldboy obj = User('Simon') print(obj.name) # Simon print(obj) # <__main__.User object at 0x0000000001E7CF98>

     三、自定义元类控制类的创建过程

    class MymetaClass(type):  # 必须是继承了type的类才是自定义元类
        def __call__(self, *args, **kwargs):
            # 1.先创建一个对象的名称空间  __new__
            # 2.往改名称空间中丢一堆名字  __init__
            # 3.产生好的对象返回出去
    
            # 1.产生一个空对象
            obj = self.__new__(self)
            # 2.实例化该对象
            self.__init__(obj, *args, **kwargs)
            # 3.返回该对象
            return obj
            # return super().__call__(*args,**kwargs)
    class Demo(metaclass=MymetaClass):  # 指定Demo的元类是MymetaClass
        pass
    obj = Demo()
    print(obj)  # <__main__.Demo object at 0x00000000027EC898>
    print(type(obj)) # <class '__main__.Demo'>
    # 标准可以直接参照这个使用
    #
    表名 主键 一对字段 class MemetaClass(type): # def __new__(cls, class_name,class_bases,class_attrs): if class_name == 'Userinfo': raise TypeError('我不想鸟你') if 'school' in class_attrs: class_attrs['school'] = 'xx最大线上xx开业啦' class_attrs['table_name'] = 'userinfo' class_attrs['primary_key'] = 'id' return type.__new__(cls,class_name,class_bases,class_attrs) class User(object,metaclass=MemetaClass): # 通过metaclass可以指定类的元类 school = 'oldboy' print(User.__dict__) """ {'__module__': '__main__', 'school': 'xx最大线上xx开业啦', 'table_name': 'userinfo', 'primary_key': 'id', '__dict__': <attribute '__dict__' of 'User' objects>, '__weakref__': <attribute '__weakref__' of 'User' objects>, '__doc__': None} """

    最详细的方法:https://www.cnblogs.com/Dominic-Ji/p/10520256.html

  • 相关阅读:
    CSS3的常用属性(一)
    Shiro授权认证原理和流程
    mysql存储引擎
    mysql索引的注意事项
    CSS的常用属性(三)
    CSS的常用属性(二)
    CSS的常用属性(一)
    常用文档站点
    Spring和SpringMVC父子容器关系初窥
    内部类学习资料分享
  • 原文地址:https://www.cnblogs.com/yangmeichong/p/10959315.html
Copyright © 2020-2023  润新知