zoukankan      html  css  js  c++  java
  • Python之反射

    1、引子:isinstance(obj,cls)和issubclass(sub,super)

    isinstance(obj,cls)检查是否obj是否是类 cls 的对象

    class Foo:
        pass
    
    obj = Foo()
    print(isinstance(obj,Foo))

    issubclass(sub, super)检查sub类是否是 super 类的派生类

    class Foo:
        pass
    
    class Bar(Foo):
        pass
    
    print(issubclass(Bar,Foo))


    2、什么是反射

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

    对象的反射

    class People:
        coutury='China'
        def __init__(self,name):
            self.name=name
    
        def walk(self):
            print('%s is walking'%self.name)
    
    p1=People('hjc')
    print(p1)
    # print(People.coutury)
    # print(p1.coutury)
    # print(People.__dict__)
    
    
    # hasattr 判断这个对象有没有响应的属性
    # print('name' in p1.__dict__) # 相当下面
    # print(hasattr(p1,'name'))  # 判断这个 name 属性在不在这个对象的 dict 里面
    # print(hasattr(p1,'coutury'))
    # print(hasattr(p1,'__init__'))
    
    # getattr 调用对象中存在的属性
    res=getattr(p1,'coutury') # 相当于 res=p1.coutury=China
    print(res)   # 对象.属性,这里 coutury 是对象的数据属性
    
    res1=getattr(People,'walk')  # 相当于 res1=People.walk=一个函数的内存地址
    print(res1)  # 类名.属性,这里 walk 是类的函数
    
    res2=getattr(p1,'walk')  # 相当于 res2=p1.walk=一个绑定方法的内存地址
    print(res2)  # 对象.属性,这里 walk 是对象的绑定方法
    
    res2()  # 相当于 res2()=p1.walk(p1) 绑定方法自动把对象传值
    res1(p1) # 相当于 res1()=People.walk(p1) 函数手动把对象传值
    
    res3=getattr(p1,'xxxxx','这个属性不存在')  # 如果属性不存在,可以给个提示
    print(res3)
    
    # 用法,可以用来判断属性存不存在,存在就执行,不存在就过
    if hasattr(p1,'walk'):
        func=getattr(p1,'walk')
        func()
    print('-------')
    
    
    # setattr
    p1.sex='male'
    print(p1.sex)
    setattr(p1,'age',18)  # 通过 setattr 可以对对象进行设置属性,格式:对象,'属性','值'
    print(p1.__dict__) # 查看有没有到 对象里面去
    print(p1.age)
    print(getattr(p1,'age')) # 取 setattr 设置的值
    
    
    # delattr
    print(p1.__dict__)
    del p1.sex   # 删除对象属性的第一种方法
    print(p1.__dict__)
    delattr(p1,'age')  # 删除对象属性的第二种方法
    print(p1.__dict__)



    模块的反射

    import sys
    
    class foo:
        pass
    
    def s1():
        pass
    
    def s2():
        pass
    
    this_module=sys.modules[__name__]
    print(this_module)   # 一个模块的对象
      
    print(hasattr(this_module,'s1'))  # 查看方式跟对象的反射一样
    print(getattr(this_module,'s2'))  # 只不过对象是模块
    print(getattr(this_module,'foo'))
    print(this_module.foo)
    print(this_module.s1)


    类的反射

    class Foo:
        f = 123
        @classmethod
        def class_method_dome(cls):
            print('class_method_dome')
    
        @staticmethod
        def static_method_dome():
            print('static_method_dome')
    
    print(hasattr(Foo,'class_method_dome'))
    method = getattr(Foo,'class_method_dome')
    method()
    print('------------')
    print(hasattr(Foo,'static_method_dome'))
    method1 = getattr(Foo,'static_method_dome')
    method1()
    


    3、为什么用反射?

    实现可插拔机制

    有俩程序员,一个lili,一个是egon,lili在写程序的时候需要用到egon所写的类,但是egon去跟女朋友度蜜月去了,还没有完成他写的类,lili想到了反射,使用了反射机制lili可以继续完成自己的代码,等egon度蜜月回来后再继续完成类的定义并且去实现lili想要的功能。

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

    ftpclient.py
    
    class FtpClient:
        'ftp客户端,但是还么有实现具体的功能'
        def __init__(self,addr):
            print('正在连接服务器[%s]' %addr)
            self.addr=addr
    
    
    ftpserver.py
    
    from ftpclient import FtpClient
    f1=FtpClient('192.168.1.1')
    if hasattr(f1,'get'):
        func_get=getattr(f1,'get')
        func_get()
    else:
        print('---->不存在此方法')
        print('处理其他的逻辑')
    .
  • 相关阅读:
    Access使用记录
    html js 表单提交前检测数据
    asp.net mvc5 action多个参数
    asp.net mvc Areas 母版页动态获取数据进行渲染
    asp.net mvc 自定义全局过滤器 验证用户是否登录
    .net 报错汇总——持续更新
    数据库基础
    Python协程
    Python 线程
    Python 队列
  • 原文地址:https://www.cnblogs.com/tootooman/p/9225303.html
Copyright © 2011-2022 走看看