• python中的元类以及反射


    一,元类

    元类也是类,它是用来创建类的类

    在默认情况下所有元类都是type

    只要是继承了type 那么这个类就变成了一个元类。

    自定义元类:

    class MyType(type):
        def __init__(self,clss_name,bases,dict):
            super().__init__(clss_name,bases,dict)
            print(clss_name,bases,dict)
            if not clss_name.istitle():
                raise Exception("你丫的 类名不会写...")
    
    # 为pig类指定了元类为MyType
    class Pig(metaclass=MyType):
        pass
    
    class Duck(metaclass=MyType):
        pass

    二,元类中的call方法:

    当你调用类对象时会自动执行元类中的__call__方法,并将这个类本身作为第一个参数传入。
    覆盖元类中的call之后,这个类就无法产生对象,必须用super().__call__ 来完成对象创建,而且还要返回值

    使用场景:

    当想要控制对象的创建过程时,就会覆盖call方法。

    当想要控制类的创建过程时,就会覆盖init 方法。

    实现将对象的所有属性名称转为大写:4

    lass MyType(type):
        def __call__(self, *args, **kwargs):
            new_args = []
            for a in args:
                new_args.append(a.upper())
    
            print(new_args)
            print(kwargs)
            return super().__call__(*new_args,**kwargs)
    
    
    class Person(metaclass=MyType):
        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
    
    p = Person(name="jack",gender="woman")
    print(p.name)
    print(p.gender)

    2.new 方法

    当创建类对象时,会首先执行元类中的__new__方法,并拿到一个空对象,然后会自动调用__init__

    初始化方法。

    如果覆盖了这个方法,那new方法必须要有返回值,而且返回值必须是类对象

    class Meta(type):
    
        def __new__(cls, *args, **kwargs):
            print(cls) # 元类自己
            print(args) # 创建类需要的几个参数  类名,基类,名称空间
            print(kwargs) #空的 
            print("new run")
            # return super().__new__(cls,*args,**kwargs)
            obj = type.__new__(cls,*args,**kwargs)
            return obj
        def __init__(self,a,b,c):
            super().__init__(a,b,c)
            print("init run")
    class A(metaclass=Meta):
        pass
    print(A)

    3.单例:

    指的是一个类产生一个对象

    单例是为了节省资源,当一个类的所有对象属性全部相同时,就没必要创建多个对象

    元类实现:

    # 单例n元类
    class Single(type):
    def __call__(self, *args, **kwargs):
    if hasattr(self,"obj"): #判断是否存在已经有的对象
    return getattr(self,"obj") # 有就返回

    obj = super().__call__(*args,**kwargs) # 没有则创建
    print("new 了")
    self.obj = obj # 并存入类中
    return obj


    class Student(metaclass=Single):
    def __init__(self,name):
    self.name = name


    class Person(metaclass=Single):
    pass

    # 只会创建一个对象
    Person()
    Person()

    三,反射

    反射指的是一个对象应该具备,可以检测,修改,增加自身属性的能力

    反射其实就是通过字符串操作属性

    1.hasattr:判断某个对象的某个属性是否存在

    2.getattr:从某个对象中取出某个属性

    3.setattr:给某个对象添加某个属性

    4.delattr:从某个对象中删除某个属性

  • 相关阅读:
    LeetCode:Symmetric Tree
    LeetCode:Construct Binary Tree from Inorder and Postorder Traversal,Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode:Binary Tree Level Order Traversal I II
    LeetCode:Binary Tree Zigzag Level Order Traversal
    LeetCode:Convert Sorted Array to Binary Search Tree,Convert Sorted List to Binary Search Tree
    LeetCode:Balanced Binary Tree
    LeetCode:Minimum Depth of Binary Tree,Maximum Depth of Binary Tree
    LeetCode:Path Sum I II
    LeetCode:Flatten Binary Tree to Linked List
    LeetCode:Distinct Subsequences
  • 原文地址:https://www.cnblogs.com/wujc3/p/11272430.html
Copyright © 2020-2023  润新知