zoukankan      html  css  js  c++  java
  • 程序的自我反省之----反射

    一、反射的概念

    是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。

    这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域采用,

    并在Lisp和面向对象方面取得了成绩。

    二、四个可以实现自省的函数

    ① hasattr(object, "属性名")

    判断object中有没有一个字符串对应得属性或方法,返回True或者False

    ② getattr (object, "属性名")

    直接拿到这个name属性或方法的内存地址,找不到会报错

    可以加默认参数,找不到则返回默认参数

    ③ setattr (object, "属性名",“属性值”)  

    设置属性,可以设置数据属性,也可设置函数属性

    ④ delattr(object, "属性名")

    class BlackMedium:
        feture = "Ugly"
        def __init__(self, name, addr):
            self.name = name
            self.addr = addr
    
        def sell_hourse(self):
            print("{}正在卖房子".format(self.name))
    
        def rent_hourse(self):
            print("{}正在租房子".format(self.name))
    
    b1 = BlackMedium('万成置地', '万置园')
    
    print(hasattr(b1,"name"))
    print(getattr(b1, "sell_hourse"))
    s = getattr(b1, "sell_hourse")()  #运行该方法
    print(getattr(b1,"aaaa","没有这个属性哦"))
    

    ③和④实例:

    class BlackMedium:
        feture = "Ugly"
        def __init__(self, name, addr):
            self.name = name
            self.addr = addr
    
        def sell_hourse(self):
            print("{}正在卖房子".format(self.name))
    
        def rent_hourse(self):
            print("{}正在租房子".format(self.name))
    
    b1 = BlackMedium('万成置地', '万置园')
    setattr(b1,"jinling","mygirlfriends")   #添加属性,等同于 b1.jinling = "mygirlfriends"
    print(b1.__dict__)
    setattr(b1,"name", "liu")  #修改属性
    print(b1.__dict__)
    setattr(b1, 'func',lambda x : x + 1)  #设置函数属性
    print(b1.__dict__)
    print(b1.func(6))  #调用上面设置的函数
    
    
    delattr(b1,"name") #删除name属性  等同于 del b1.name
    print(b1.__dict__)
    

      

    三、为什么用反射

    反射的好处就是,可以事先定义好接口,接口只有在被完成后才真正执行,这实现了即插即用,这其实是一种'后期绑定',

    即你可以事先把主要的逻辑写好(只定义接口),然后后期再实现接口的功能

    ################################

    前面四个函数也可作用于类,因为类本质上也就是对象

    ① __getattr__

    class Foo:
        x = 2
        def __init__(self,y):
            self.y = y
    
        def __getattr__(self, item):
            print('执行__getattr__')
    
    f1 = Foo(7)
    print(getattr(Foo,'x'))
    f1.z  #当实例调用不存在的属性时会触发 __getattr__函数
    

      

    ② __delattr__

    class Foo:
        x = 2
        def __init__(self,y):
            self.y = y
    
        def __delattr__(self, item):
            print("正在执行__delattr__")
    
    f1 = Foo(7)
    del f1.x
    del f1.y
    

     

    ③ __setattr__

    class Foo:
        x = 2
        def __init__(self,y):
            self.y = y
    
        def __setattr__(self, key, value):
            print("正在执行__setattr__")
            self.__dict__[key] = value
    
    f1 = Foo(7) #实例化的时候创建了 y = 7,所以触发了 __setattr__
    f1.z = 6  #触发__setattr__
    print(f1.__dict__)
    

      

    四、模块也能用反射,因为一切皆对象

    import sys
    obj = sys.modules[__name__]
    #拿到当前文件的模块对象
    #拿到后就能用反射啦
    

      

     

    一个奋斗中的产品小白
  • 相关阅读:
    第三次作业,结对编程
    第二次作业
    第一次作业
    最小环问题
    拓扑排序——烦人的幻灯片
    拓扑排序——奖金
    洛谷——P2330 [SCOI2005] 繁忙的都市
    洛谷——P2820 局域网
    最小生成树——最短网络Agri-Net
    最小生成树——城市公交网建设问题
  • 原文地址:https://www.cnblogs.com/dabai123/p/11595178.html
Copyright © 2011-2022 走看看