zoukankan      html  css  js  c++  java
  • 反射

    反射

    什么是反射

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

    python中面向对象的反射

    通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

    四个可以实现自省的函数

    用户输入一段字符串,执行该字符串对应的方法

    hasattr():判断一个属性是否在对象中,返回True或False

    getattr():通过字符串获取属性方法,如果获取到了,就会返回相应的属性或方法

    setattr():通过字符串来设置属性或方法

    delattr():通过字符串来删除属性或方法

    class Foo:
        def run(self):
            print('run')
        def speak(self):
            print('speak')
    p=Foo()
    print(Foo.__dict__)
    cmd=input('请输入命令: ')
    print(Foo.__dict__)
    Foo.__dict__[cmd](p)
    if hasattr(p,cmd):
        run=getattr(p,cmd)
        run()
    else:
        print('该命令不存在')
    
    
    # 通过用户输入key和value往对象中赋值
    key=input('请输入key:')
    value=input('输入value:')
    setattr(p,key,value)
    print(p.age)
    
    
    #动态的往对象中放方法
    def test(a):
        print(a)
    print(p.__dict__)
    setattr(p,'test',test)
    print(p.__dict__)
    p.test(0)
    
    #原始的删除方法
     p.name='lqz'
     print(p.__dict__)
     del p.name
     print(p.__dict__)
    
    #动态删除p中属性为变量a的属性
    p.name='lqz'
    p.age=18
    p.sex='male'
    a=input('请输入要删除的属性:')
    print(p.__dict__)
    delattr(p,a)
    print(p.__dict__)
    #直接p.a是不对的
    #del p.a
    

    例子

    class BlackMedium:
        feature='Ugly'
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
    
        def sell_house(self):
            print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name)
        def rent_house(self):
            print('%s 黑中介租房子啦,傻逼才租呢' %self.name)
    
    b1=BlackMedium('万成置地','回龙观天露园')
    
    #检测是否含有某属性
    print(hasattr(b1,'name'))
    print(hasattr(b1,'sell_house'))
    
    #获取属性
    n=getattr(b1,'name')
    print(n)
    func=getattr(b1,'rent_house')
    func()
    
    # getattr(b1,'aaaaaaaa') #报错
    print(getattr(b1,'aaaaaaaa','不存在啊'))
    
    #设置属性
    setattr(b1,'sb',True)
    setattr(b1,'show_name',lambda self:self.name+'sb')
    print(b1.__dict__)
    print(b1.show_name(b1))
    
    #删除属性
    delattr(b1,'addr')
    delattr(b1,'show_name')
    delattr(b1,'show_name111')#不存在,则报错
    
    print(b1.__dict__)
    
    四个方法的使用演示
    

    模块也是对象,也可以用四个方法

    import  os
    print(hasattr(os,'path1'))
    

    使用自己写的模块,通过反射来获取模块中是否有我要使用的属性或方法,如果有就执行,没有,就报错

    import utils
    
    utils.speak()
    if hasattr(utils,'speak'):
        speak=getattr(utils,'speak')
        speak()
    

    反射的好处

    可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

    #我以为它写完了
    utils.eat()
    #更安全
    if hasattr(utils,'eat'):
        eat=getattr(utils,'eat')
        eat()
    else:
        print('那个人还没写完呢')
    
  • 相关阅读:
    Perl的比较操作符
    Perl的变量
    应用负载均衡之LVS(五):lvs和nginx的wrr加权调度算法规律分析
    sharding:谁都能读懂的分库、分表、分区
    MySQL中间件之ProxySQL(15):ProxySQL代理MySQL组复制
    MySQL中间件之ProxySQL(12):禁止多路路由
    MySQL中间件之ProxySQL(14):ProxySQL+PXC
    haproxy(8):haproxy代理MySQL要考虑的问题
    PXC快速入门
    vscode指定扩展安装位置
  • 原文地址:https://www.cnblogs.com/aden668/p/11448765.html
Copyright © 2011-2022 走看看