• python面向对象


    1.  isinstance

    isinstance(obj,cls)检查obj是否是类 cls 的对象

    print(isinstance(1, int))
    
    print(isinstance(1.0, float))
    
    print(isinstance('aa', str))

    上面都是True

     print(isinstance('aa', (int,list,str))) 

    只要是后面元组中的一个,就返回True

    2.   issubclass

    issubclass(sub, super)检查sub类是否是 super 类的派生类

    class A:
        pass
    
    class B(A):
        pass
    
    class C(B):
        pass
    
    class D:
        pass
    
    print(issubclass(B,A))
    print(issubclass(C,A))
    print(issubclass(D,A)

    结果是:

    True
    True
    False
    

    子类的子类,进行判断,返回也是True,不能用实例化的对象进行判断,例如:b=B(),issubclass(b,A) ,这样有语法错误

     

    反射

    python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr

    class A:
        def __init__(self,name,age):
            self.names=name
            self.ages=age
    
        def info(self):
            print('name: %s, age: %d' %(self.names,self.ages))
    
        @staticmethod
        def static_func():
            print('static method')
    
    a=A('egon',18)
    
    print(hasattr(a,'name'))  #判断是否有name属性,False
    print(hasattr(a,'names')) #判断是否有names属性,True
    
    #获取属性
    n = getattr(a,'names')
    print(n)  #egon
    func = getattr(a,'info')
    func()  #name: egon, age: 18
    m = getattr(a,'bbbbb','不存在') #如果属性不存在,返回第三个字段内容
    print(m)  #不存在
    m = getattr(a,'bbbbb',None)
    print(m) #None
    
    #设置属性
    setattr(a,'names','alex')
    print(a.__dict__)  #{'names': 'alex', 'ages': 18}
    setattr(a,'n','alex')
    print(a.__dict__)  #{'names': 'alex', 'ages': 18, 'n': 'alex'} 新增了一个n属性
    
    #删除属性
    
    #delattr(a,'ddd') #删除的属性不存在会报错
    delattr(a,'names')
    print(a.__dict__)  #{'ages': 18, 'n': 'alex'} 已经删除掉了names
    
    #可以直接获取类的属性
    f = getattr(A,'static_func')
    f()  #static method

    __setattr__,__delattr__,__getattr__

    __getattr__只有在使用点调用属性且属性不存在的时候才会触发
    __delattr__删除属性的时候会触发
    __setattr__添加/修改属性会触发它的执行
    class Foo:
        x=1
        def __init__(self,y):
            self.y=y
    
        def __getattr__(self, item):
            print('----> from getattr:你找的属性不存在')
    
    
        def __setattr__(self, key, value):
            print('----> from setattr')
            # self.key=value #这就无限递归了,你好好想想
            # self.__dict__[key]=value #应该使用它
    
        def __delattr__(self, item):
            print('----> from delattr')
            # del self.item #无限递归了
            self.__dict__.pop(item)
    
    #__setattr__添加/修改属性会触发它的执行
    f1=Foo(10)
    print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
    f1.z=3
    print(f1.__dict__)
    #
    #__delattr__删除属性的时候会触发
    f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
    del f1.a
    print(f1.__dict__)
    #
    # #__getattr__只有在使用点调用属性且属性不存在的时候才会触发
    f1.xxxxxx
    f1.__dict__['a']=3
    f1.a

    __setitem__,__getitem,__delitem__

    当已字典的形式操作类属性的时候,会进入以上函数

    class Foo:
        def __init__(self,name):
            self.name=name
    
        def __getitem__(self, item):
            print('--------getitem',self.__dict__[item])
    
        def __setitem__(self, key, value):  #f1['age']=18,当以操作字典的形式进行操作时,会进入该函数
            print('--------setitem')
            self.__dict__[key]=value
        def __delitem__(self, key):  #del f1['age']已字典形式删除时进入函数
            print('del obj[key]时,我执行')
            self.__dict__.pop(key)
        def __delattr__(self, item):  #del f1.age1,obj.xxx 进行操作时,进入函数
            print('del obj.key时,我执行')
            self.__dict__.pop(item)
    
    f1=Foo('sb')
    f1['age']=18  #--------setitem
    f1['age1']=19 #--------setitem
    del f1.age1     #del obj.key时,我执行
    del f1['age']   #del obj[key]时,我执行
    f1['name']='alex'   #--------setitem
    print(f1.__dict__)  #{'name': 'alex'}

    __str__,__repr__,__format__

    改变对象的字符串显示__str__,__repr__

    自定制格式化字符串__format__

    format_dict={
        'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
        'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
        'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
    }
    class School:
        def __init__(self,name,addr,type):
            self.name=name
            self.addr=addr
            self.type=type
    
        def __repr__(self):
            return 'School(%s,%s)' %(self.name,self.addr)
        def __str__(self):
            return '(%s,%s)' %(self.name,self.addr)
    
        def __format__(self, format_spec):
            # if format_spec
            if not format_spec or format_spec not in format_dict:
                format_spec='nat'
            fmt=format_dict[format_spec]
            return fmt.format(obj=self)
    
    s1=School('oldboy1','北京','私立')
    print('from repr: ',repr(s1))
    print('from str: ',str(s1))
    print(s1)
    
    '''
    str函数或者print函数--->obj.__str__()
    repr或者交互式解释器--->obj.__repr__()
    如果__str__没有被定义,那么就会使用__repr__来代替输出
    注意:这俩方法的返回值必须是字符串,否则抛出异常
    '''
    print(format(s1,'nat'))   #oldboy1-北京-私立
    print(format(s1,'tna'))   #私立:oldboy1:北京
    print(format(s1,'tan'))   #私立/北京/oldboy1
    print(format(s1,'asfdasdffd'))  #oldboy1-北京-私立

     __doc__

    class Foo:
        '我是描述信息'
        pass
    
    class Bar(Foo):
        pass
    print(Bar.__doc__) #该属性无法继承给子类 None
    print('---------------')
    print(Foo.__doc__)  #我是描述信息

    __del__

    析构方法,当对象在内存中被释放时,自动触发执行。

    class Foo:
    
        def __del__(self):
            print('执行我啦')
    
    f1=Foo()
    # del f1
    print('------->')

    结果是:

    ------->
    
    执行我啦
  • 相关阅读:
    逆元应用求组合数
    树的重心入门
    扫描线求面积的并,交
    涂抹果酱
    牧场的安排
    「SCOI2005」互不侵犯
    Network Coverage
    Linux命令传输文件
    VMware Workstation 与 Device/Credential Guard 不兼容.在禁用 Device/Credenti
    Springboot开启SpringSecurity
  • 原文地址:https://www.cnblogs.com/litzhiai/p/8024334.html
Copyright © 2020-2023  润新知