• 面向对象之反射


    反射:

    反射就是反省自省的意思。

    反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。

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

    四个可以实现自省的函数:hasattr;getattr;setattr;delattr

    hasattr:

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

    # hasattr
    
    class Person:
        def __init__(self,name,age,gender):
            self.name = name
            self.age = age
            self.gender = gender
    p = Person("jack",18,"man")
    print(p.name)
    print(hasattr(p,"name"))  # 判断某个对象是否存在某个属性

    getattr:

    从对象中取出属性,当对象中有默认值的时候,属性不存在的时候会返回默认值。

    # getattr
    
    class Person:
        def __init__(self,name,age,gender):
            self.name = name
            self.age = age
            self.gender = gender
    p = Person("jack",18,"man")
    print(p.name)
    print(hasattr(p,"name"))
    if hasattr(p,"name"): # 判断某个对象是否存在某个属性
        print(getattr(p,"names",None)) # 从对象中取出属性,第三个值位默认值 当属性不存在是返回默认值

    setattr:

    为对象添加新属性

    # setattr
    
    class Person:
        def __init__(self,name,age,gender):
            self.name = name
            self.age = age
            self.gender = gender
    p = Person("jack",18,"man")
    print(p.name)
    # 为对象添加新的属性
    setattr(p,"id","123")
    print(p.id)

    delattr:

    从对象中删除属性

    # delattr
    
    class Person:
        def __init__(self,name,age,gender):
            self.name = name
            self.age = age
            self.gender = gender
    p = Person("jack",18,"man")
    print(p.name)
    delattr(p,"name")
    print(p.name)
    
    
    """
    反射其实就是对属性的增删改查,但是如果直接使用内置的__dict__来操作,语法繁琐,不好理解 
    另外一个最主要的问题是,如果对象不是我自己写的是另一方提供的,我就必须判断这个对象是否
    满足的要求,也就是是否我需要的属性和方法  
    """

    框架:

    反射被称为框架的基石,为什么

    因为框架的设计者,不可能提前知道你的对象到底是怎么设计的

    所以你提供给框架的对象 必须通过判断验证之后才能正常使用

    判断验证就是反射要做的事情,当然通过__dict__也是可以实现的,

    其实这些方法也就是对__dict__的操作进行了封装。

    元类:

    元类是什么?元类是用于创建类的类,

    万物皆对象,类当然也是对象

    对象是通过类实例化产生的,如果类也是对象的话,

    必然类对象也是有另一个类实例化产生的

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

    验证:

    class Person:
        pass
    p = Person()
    print(type(p))
    print(type(Person))
    
    
    """Person类是通过type类实例化产生的 """

    我们学习元类的目的:

    高度的自定义一个类,例如控制类的名字必须以大驼峰体的方式来书写。

    类也是对象,也有自己的类:

    """
    我们的需求是创建类对象做一些限制 
    想到了初始化方法  我们只要找到类对象的类(元类),覆盖其中 init方法就能实现需求 
    当然我们不能修改源代码,所以应该继承type来编写自己的元类,同时覆盖init来完成需求
    """
    
    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
    
    
    """ 只要继承了type 那么这个类就变成了一个元类 """

    元类中call方法:

    当你调用类对象时,会自动执行元类中__call__方法,并将这个类本身作为第一个参数传入

    以及后面的一堆参数覆盖元类中的__call__之后,这个类就无法产生对象,必须调用super().__call__

    来完成对象的创建并返回其的返回值。

    使用场景:

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

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

    class MyMeta(type):
        def __init__(self,name,bases,dict):
            super().__init__(name,bases,dict)
            print("init run")
        def __call__(self, *args, **kwargs):
            print("元类 call run")
            print(self)
            print(args)
            print(kwargs)
            return super().__call__(*args,**kwargs)
    class Dog(metaclass=MyMeta): # ===    Dog = MyMate("Dog",(),{})
        def __init__(self,name):
            self.name = name
        def __call__(self, *args, **kwargs):
            print("call run")
    d = Dog("大黄")
    d = Dog("旺财")
    print(d.name)
    
    """一旦覆盖了call必须调用父类的call方法来产生对象并返回这个对象 """

     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)
    
    
    """ new方法和init 都可以实现控制类的创建过程,init更简单 """

    单例设计模式:

    单例设计模式主要用于解决某种固定问题的套路
    例如:MVCMTV等
    单例:它指的是一个类产生一个对象
    为什么要使用单例:单例是为了节省 资源,当一个类的所有对象属性全部相同时,则没有必要创建
    多个对象

    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 - (圈数索引)

    l = [9, 587, 2, 616, 5, 1, 3, 69, 4, 8, 8, 43, 9, 32, 56, 55, 35, 45, 25, 15,]
    for i in range(len(l) - 1):
        for j in range(len(l) - 1 - i):
            if l[j] < l[j+1]:
                l[j], l[j+1] = l[j+1], l[j]
    print(l)
    
    """ 从大到小排 """
  • 相关阅读:
    一些有用的正则
    UNION ALL合表查询
    远程桌面连接:出现身份验证错误,要求的函数不受支持,可能是由于CredSSP加密Oracle修正的解决方法
    Ubuntu20.04安装、配置openvas
    awvs13破解安装、批量扫描脚本
    剑指05题
    时间复杂度o(1), o(n), o(logn), o(nlogn)
    Intellij IDEA 注释模板
    Explain详解
    Hibernate中get()和load()的区别
  • 原文地址:https://www.cnblogs.com/sweet-i/p/11272580.html
Copyright © 2020-2023  润新知