zoukankan      html  css  js  c++  java
  • python基础--反射、元类、单例设计模式

    反射:reflect,反射指的是一个对象应该具备可以检测、修改、增加自身属性的能力,反射就是通过字符串操作属性

        hasattr(对象,带查询的属性名称) 

            判断某个对象中是否存在某个属性

        getattr

            从指定对象中取出属性,第三个参数为默认值,当参数不存在时返回的就是默认值

        setattr

            为对象添加新的属性

        delattr

            从对象中删除属性

        使用场景:

            反射其实就是对属性的增删改查,但是如果直接用dict来操作的话,语法繁琐,而且不是很好理解,另外一个主要的问题是,如果对象不是我自己写的是另一方提供的,我就必须要判断这个对象是否满足我的要求,也就是是否是我要的属性和方法

        框架的基石:

            原因: 因为框架的设计者,不可能提前知道你的对象到底是怎么设计的,所以你提供给框架的对象 必须通过判断验证之后才能正常使用,判断验证就是反射要做的事情,当然通过__dict__也是可以实现的, 其实这些方法也就是对__dict__的操作进行了封装,

            

    元类:metaclass

        是什么:就是用于创建类的类,万物皆是对象,当然类也是对象

        对象是通过类实例化产生的,如果类也是对象的话,必然类对象也是有另一个类实例化产生的

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

        好处:高度的自定义一个类,类也是对象,也有自己的类

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

            使用场景:

                当你想要控制对象的创建过程时,就需要覆盖__call__方法

            案例:将所有属性名称转换为大写

    class Mytype(type):
        def __call__(self, *args, **kwargs):
            new_args = []
            for i in args:
                new_args.append(i.upper())
    
            return super().__call__(*new_args, **kwargs)
    
    
    class Person(metaclass=Mytype):
        def __init__(self, name):
            self.name = name
    
    
    p = Person('william')
    print(p.name)

            一旦覆盖了call之后,就必须要调用父类的call方法来产生对象并且返回这个对象

        __init__方法:

            使用场景:

                当你想要控制类的创建过程时,就覆盖__init__方法

        

        __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)

        单例设计模式:

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

    class meta(type):
        def __call__(self, *args, **kwargs):
            if hasattr(self, "obj"):
                return getattr(self, "obj")
            obj = super().__call__(*args, **kwargs)
            self.obj = obj
            print('创建了一个....')
            return obj
    
    
    class Student(metaclass=meta):
        def __init__(self, name):
            self.name = name
    
    
    s1 = Student('william')
    s2 = Student('william')
    s3 = Student('william')
    s4 = Student('william')
  • 相关阅读:
    Javascript数组与字符串常用api
    javaScript入门(函数)
    javascript入门(1)
    微信小程序组件解读和分析:一、view(视图容器 )
    微信小程序组件解读和分析:十五、switch 开关选择器
    微信小程序组件解读和分析:十四、slider滑动选择器
    微信小程序组件解读和分析:十三、radio单选项目
    微信小程序组件解读和分析:十二、picker滚动选择器
    微信小程序组件解读和分析:十一、label标签
    微信小程序组件解读和分析:十、input输入框
  • 原文地址:https://www.cnblogs.com/tulintao/p/11272074.html
Copyright © 2011-2022 走看看