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

 

posted @ 2019-07-30 19:01  tulintao  阅读(209)  评论(0编辑  收藏  举报