• 十三、反射(自省)


    一、 反射(自省):主要是指程序可以访问、检测和修改它本身状态或行为的一种能力

      四个可以实现自省的函数:

      1、hasattr(object,name)     

        object--->对象,name--->字符串

        判断object中有没有一个name字符串对应的方法或属性

    class AAA:
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
        def sale(self):
            print('----->')
    p1=AAA('alex','nanjing')
    print(hasattr(p1,'name'))   #True 
    print(hasattr(p1,'sale'))    #True
    print(hasattr(p1,'shugl'))    #False

      2、getattr(object,name,default=None)

        运行object对象所对应的name方法。若指定了default,不存在name时显示default内容,不指定时报错

    class AAA:
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
        def sale(self):
            print('----->')
    p1=AAA('alex','nanjing')
    print(getattr(p1,'name'))   # alex
    print(getattr(p1,'sale'))    #返回sale函数的内存地址
    func=getattr(p1,'sale')
    func()        #----->
    print(getattr(p1,'shugl','没有这个参数'))    #没有这个参数
    print(getattr(p1,'shugl'))    #报错

      3、setattr(object,name,value)

        设置object对象的name属性值为value

    class AAA:
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
        def sale(self):
            print('----->')
    p1=AAA('alex','nanjing')
    setattr(p1,'name','alex1234')  
    print(p1.name)    #alex1234
    setattr(p1,'age',30)
    print(p1.__dict__)   #{'age':'30','name':'alex','addr':'nanjing'}

       给对象设置函数属性

    class AAA:
        def __init__(self,name):
            self.name=name
        def sale(self):
            print('----->')
    p1=AAA('alex')
    setattr(p1,'func',lambda x:x+1)
    print(p1.__dict__)   #{'name':'alex','func':<function <almbda> at 0x00BF 17CB>}
    setattr(p1,'func1',lambda self:self+'-nanjing')
    print(p1.func(10))            #11
    print(p1.func1('alexxxxx'))   #alexxxxx-nanjing

      4、del (object,name)

        删除object对象的name属性

    class AAA:
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
        def sale(self):
            print('----->')
    p1=AAA('alex','nanjing')
    print(p1.__dict__)     #{'name':'alex','addr':'nanjing'}
    delattr(p1,'name')  
    print(p1.__dict__)   #{'addr':'nanjing'}

     二、反射的好处

        实际项目中,经常是多个程序员一起合作一个项目,使用反射可以帮助程序员之前开发代码互不影响

    #程序员1开发代码
    class FtpClient:
        'ftp客户端,但是没有实现具体功能'
        def __init__(self,addr):
            self.addr=addr
            print('正在连接服务器%s'%(self.addr))
            
    #程序员2开发代码
    from ftp_wenjian import FtpClient
    f1=FtpClient('192.168.10.208')
    if hasattr(f1,'put'):
        func=getattr(f1,'put')
        func()
    else:
        print('没有方法put')

    三、类内置的attr方法

    1. __getattr__

       只有在调用的属性不存在时,才会执行__getattr__

    class Foo:
        def __init__(self,y):
            self.y=y
        def __getattr__(self,item):
            print('执行__getattr__')
    
    f1=Foo(10)
    print(f1.y)   #10 
    print(getattr(f1,'y'))  #10
    f1.ssss   #执行__getattr__
    print(f1.shug)   #执行__getattr__
                     #None 

    2. __delattr__

      无论要删除的属性是否存在,都会执行__delattr__

      但是实际上,属性并没有被删除!!!需要在__delattr__中删除

    class Foo:
        def __init__(self,y):
            self.y=y
        def __delattr__(self,item):
            print('删除操作')
         #self.__dict__.pop(item) f1
    =Foo(10) del f1.y #删除操作 print(f1.__dict__) #{'y':10} del f1.x #删除操作

    3. __setattr__

    class Foo:
        x=1
        def __init__(self,y,z):
            self.y=y
         self.z=z
    def __setattr__(self,key,value): #self.key=value #不能这样设置,会进入死循环 print('--->') self.__dict__[key]=value #生成实例时启动__setattr__时,不会将属性自动加到实例的属性字典,所以需要手动加 f1=Foo(10)

    #--->
    #--->
     
  • 相关阅读:
    数据库路由中间件MyCat
    数据库路由中间件MyCat
    数据库路由中间件MyCat
    数据库路由中间件MyCat
    数据库路由中间件MyCat
    数据库路由中间件MyCat
    数据库路由中间件MyCat
    数据库路由中间件MyCat
    SQL Server 调用dll
    windows7 Sql server 2012 尝试读取或写入受保护的内存。这通常指示其他内存已损坏的修复
  • 原文地址:https://www.cnblogs.com/haoy/p/10564126.html
Copyright © 2020-2023  润新知