zoukankan      html  css  js  c++  java
  • python 反射 (自省)

    python中反射是指通过字符串的形式操作对象相关属性。在python中,一切皆对象(只要是对象,都可以通过python的反射机制进行处理)
      在做程序开发中,我们常常会遇到这样的需求:需要执行对象里的某个方法,或需要调用对象中的某个变量,但是由于种种原因我们无法确定这个方法或变量是否存在,这是我们需要用一个特殊的方法 或机制要访问和操作这个未知的方法或变量,这中机制就称之为反射。
      四个可以实现自省的函数 hasattr()  getattr()  setattr() delattr()
      class Stu:
           def __init__(self,name,age,stuid):
               self.name=name
               self.age=age
               self.stuid=stuid


          def study(self):
             print("good good study,day day up")

    #判断对象中是否包含该属性 hasattr(Obj,attr)
    s=Stu("史莱克",18,6100116003)
    print(hasattr(s,"name"))
    print(hasattr(s,"play_game"))
     
    运行代码,执行结果为:
    True
    False
     
     
    #获取属性
    print(getattr(s, "name"))
    print(getattr(s,"greet"))#getattr(Obj,attr)当只有两个参数时,访问不存在的属性时,会报错
     
     
    运行代码,执行结果为:
    史莱克
    Traceback (most recent call last):
      File "F:/python/stuDemo/002.py", line 18, in <module>
        print(getattr(s,"greet"))#getattr(Obj,attr)当只有两个参数时,访问不存在的属性时,会报错,将会促发AttributeError
    AttributeError: 'Stu' object has no attribute 'greet'


    print(getattr(s,"grade",90))#getattr(Obj,attr,default),存在三个参数时,如果属性不存在,就会返回一个默认值,不会报错
     
     
    运行结果为:
    90
     
     
    也许你会猜想这样一种情况,getattr()存在三个参数时,如果属性不存在,会在该对象的属性字典中添加该属性,并返回属性值,那么我们就来看一下s的属性字典,结果是;
    {'name': '史莱克', 'age': 18, 'stuid': 6100116003}
    很显然,这证明了,我们的猜想是错误的,说明第三个参数只是我们自己设置的默认返回值
     
     
    #设置属性setattr(Obj,"key",value)
     
    setattr(s,"name","菠萝吹雪")#修改已经存在的属性
    print(s.__dict__)
     
     
    运行代码,执行结果为:
    {'name': '菠萝吹雪', 'age': 18, 'stuid': 6100116003}
     
     
     
    setattr(s,"weight",160)#设置一个不存在的属性,则会在对象的属性字典上添加该属性
    print(s.__dict__)
    运行代码,执行结果为:
    {'name': '史莱克', 'age': 18, 'stuid': 6100116003, 'weight': 160}
     
     
     
     
    #设置方法属性
    def play_game():
       print("来啊快活啊")
    setattr(s,"play_game",play_game)
    print(s.__dict__)
    运行结果为:
    {'name': '史莱克', 'age': 18, 'stuid': 6100116003, 'weight': 160, 'play_game': <function play_game at 0x00000000021D2E18>}
     
     
     
    #删除属性
    delattr(obj,attr)
     
    delattr(s,"play_game")
    print(s.__dict__)
    运行结果为:
    {'name': '史莱克', 'age': 18, 'stuid': 6100116003, 'weight': 160}
     
     
     
    delattr(s,"aaaaa")#删除不存在的属性
     
     
    结果为:
    Traceback (most recent call last):
      File "F:/python/stuDemo/002.py", line 39, in <module>
        delattr(s,"aaaaa")##删除不存在的属性
    AttributeError: aaaaa

     
     
     
     





                    __setattr__ __delattr__() __getattr__()


    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
     
     
     
    在我身后,微笑地活下去吧。
  • 相关阅读:
    Java的HttpRequest请求工具类
    js改变this指向的三种方式call() apply() bind()
    CSS3——弹性盒模型-flex——子级属性
    CSS3——弹性盒模型-flex——父级属性
    CSS3——文本延申扩展系列、多列
    CSS3——IE6混杂盒模型(box-sizing)
    CSS3——@font-face(文字字体包)
    CSS3——文本延申扩展系列—text-shadow
    CSS3—— border-radius
    CSS3——border-image
  • 原文地址:https://www.cnblogs.com/L-C98/p/9121503.html
Copyright © 2011-2022 走看看