zoukankan      html  css  js  c++  java
  • 反射/内置方法

    反射/内置方法

    issubclass和ininstance

    # 判断第一个类是不是第二个类的子类,返回true或者false
    class Foo:    
    	pass
    class Bar(Foo):    
    	pass
    class Tt(Bar):    
    	pass
    
    print(Bar.__bases__) # (<class '__main__.Foo'>,)
    print(issubclass(Bar,Foo)) # True
    print(issubclass(Tt,object)) # True
    
    # 判断第一个参数是不是第二个参数的对象,返回true或者false
    class Foo:
        pass
    class Tt():
        pass
    f=Foo()
    
    print(isinstance(f,Foo)) # True
    print(isinstance(f,Tt)) # False
    

    反射

    反射就是通过字符串来操作类或者对象的属性

    • 反射本质就是在使用内置函数,其中反射有以下四个内置函数:

      1. hasattr:判断一个方法是否存在与这个类中
      2. getattr:根据字符串去获取obj对象里的对应的方法的内存地址,加"()"括号即可执行
      3. setattr:通过setattr将外部的一个函数绑定到实例中
      4. delattr:删除一个实例或者类中的方法
      
    class Foo:
        def run(self):
            print('run')
        def speak(self):
            print('speak')
    p=Foo()
    
    # 输入字符串,执行字符串对应的方法
    choice = input('请输入执行命令:')
    if hasattr(p,choice):
        run = getattr(p,choice)
        run()
    else:
    	print('该命令不存在!') 
        
    # 通过用户输入key和value往对象中赋值
    key=input('请输入key:')
    value=input('输入value:')
    setattr(p,key,value)
    print(p.age)  # 默认用户输入age关键字
    '''
    请输入key:age
    输入value:12
    12
    '''
    
    #动态的往对象中放方法
    def test():
        print(1)
        
    print(p.__dict__)
    setattr(p,'test',test)
    print(p.__dict__)
    
    p.test()
    '''
    {}
    {'test': <function test at 0x02D907C8>}
    1
    '''
    
    # 动态删除p中属性为变量a的属性
    p.name='lqz'
    p.age=18
    p.sex='male'
    a=input('请输入要删除的属性:')
    print(p.__dict__)
    delattr(p,a)
    print(p.__dict__)
    '''
    请输入要删除的属性:age
    {'name': 'lqz', 'age': 18, 'sex': 'male'}
    {'name': 'lqz', 'sex': 'male'}
    '''
    
    # 直接p.a是不对的
    del p.a
    

    内置方法

    #__str__:如果不重写__str__   print打印会打印出内存地址
    class Foo:
        def __init__(self,name):
            self.name=name
    print(Foo('nick')) # <__main__.Foo object at 0x0078DFD0>
    
    # __str__如果重写了,就会打印__str__方法返回的内容
    class Foo:
        def __init__(self,name):
            self.name=name
        def __str__(self):
            return '['+self.name+']'
    
    print(Foo('nick')) # [nick]
    
    #__repr__ 跟str类似,在交互式命令下直接写变量名,会执行__repr__
    
    #__setattr__,__delattr__,__getattr__(重要)
    # 点拦截方法
    #如果去对象中取属性,一旦取不到,会进入到__getattr__
    #如果去对象中赋值属性,一旦取不到,会进入到__setattr__
    #如果删除对象中的属性,会进入__delattr__
    
    class Foo:
        def __init__(self,name):
            self.name=name
        def __getattr__(self, item):
            return '你傻逼啊,没有这个字段'
        
    f=Foo('nick')
    print(f.age) # 你傻逼啊,没有这个字段
    
    
    class Foo:
        def __init__(self,name):
            self.name=name
        def __setattr__(self, key, value):
            print('6666')
    f=Foo('nick')
    f.sex='male' # 666
    
    
    class Foo:
        def __init__(self,name):
            self.name=name
        def __delattr__(self, item):
            print('你想删除啥?')
    f=Foo('nick')
    del f.name
    print(f.__dict__) # name属性并没有被删除
    '''
    你想删除啥?
    {'name': 'nick'}
    '''
    
    # 写一个类继承字典,让它可以 . 取值,也可以中括号取值
    class Mydict(dict):
        def __init__(self,**kwargs):
            super().__init__(**kwargs) # 继承了原dict的方法
    
        def __getattr__(self, item):
            return self[item]
    
        def __setattr__(self, key, value):
            self[key]=value
            
    di=Mydict(name='lqz',age=18)
    print(di['name'])
    print(di.age)
    di.sex='male'
    di['sex']='male'
    di.hobby = ['baskerball']
    print(di.sex)
    print(di['hobby'])
    '''
    lqz
    18
    male
    ['baskerball']
    '''
    
    # __item__系列  对象通过[] 中括号取值,赋值,删除值的时候,会调用
    __setitem__:中括号赋值时触发
    __getitem__:中括号取值时触发
    __delitem__:中括号删除时触发
    __delattr__:.删除时触发
        
    class Foo:
        def __init__(self, name):
            self.name = name
    
        def __getitem__(self, item):
            print('getitem执行', self.__dict__[item])
    
        def __setitem__(self, key, value):
            print('setitem执行')
            self.__dict__[key] = value
    
        def __delitem__(self, key):
            print('del obj[key]时,delitem执行')
            self.__dict__.pop(key)
    
        def __delattr__(self, item):
            print('del obj.key时,delattr执行')
            self.__dict__.pop(item)
    
    f1 = Foo('sb')
    
    f1['age'] = 18       # setitem执行
    f1['name'] = 'tank'  # setitem执行
    
    f1['age']   # getitem执行 
    
    del f1.age     # del obj.key时,delattr执行
    del f1['age']   # del obj[key]时,delitem执行
    
    print(f1.__dict__)   # {'name': 'tank'}
    
    #__call__   对象加括号会调用它
    class Foo:
        def __call__(self):
            print('xxxx')
            
    f=Foo()
    f()   # xxxx
    
  • 相关阅读:
    [CF724G]Xor-matic Number of the Graph
    [SOJ #537]不包含 [CF102129I]Incomparable Pairs(2019-8-6考试)
    [SOJ #538]好数 [CC]FAVNUM(2019-8-6考试)
    [洛谷P4052][JSOI2007]文本生成器
    [洛谷P3966][TJOI2013]单词
    [洛谷P5158]【模板】多项式快速插值
    [洛谷P3227][HNOI2013]切糕
    【bzoj】3477: [Usaco2014 Mar]Sabotage 01分数规划
    【SPOJ
    【以前的空间】系列
  • 原文地址:https://www.cnblogs.com/dadazunzhe/p/11448574.html
Copyright © 2011-2022 走看看