zoukankan      html  css  js  c++  java
  • python反射

    python反射

    python的反射是基于字符串的形式去对象(模块)中操作其成员。此操作是动态的,常用于web开发中url参数中对应模块或者函数的反射。
    下面开始具体说明:

    • 场景需求:

    我的python脚本中有一百个函数,当前端页面被访问到之后,针对特定的url 我后端有特定的函数进行处理,我该如何判断这个URL需要后端那个函数来处理呢?写if判断?别闹了。一百多个呢,那执行效率会有多慢。看下面代码:

    def f1():
        print("f1")
    
    def f2():
        print("f2")
    
    
    def f3():
        print("f3")
    
    res = input("请输入url: ")
    if res == 'f1':
        f1()
    elif res == 'f2':
        f2()
    elif res == 'f3':
        f3()
    else:
        print("404")
        
    执行结果:
    请输入url: f1
    f1
    
    请输入url: f2
    f2
    
    请输入url: f3
    f3
    
    请输入url: adasd
    404

    现在是定义了3个函数,如果100个的,我得写100个if判断,那不疯了。。。
    下面耍个小聪明,使用dict映射来做

    def f1():
        print("f1")
    
    def f2():
        print("f2")
    
    
    def f3():
        print("f3")
    
    func_map = {
        'f1':f1,
        'f2':f2,
        'f3':f3,
    }
    res = input("请输入url: ")
    
    if res in func_map:
        func_map[res]()
    else:
        print('404')
        
     输出结果:
     
     
    请输入url: f1
    f1
    
    请输入url: f2
    f2
    
    请输入url: f3
    f3
    
    请输入url: asdad
    404

    发现还是很麻烦。字典需要写很长影射,而且后期我加一个函数,还得在字典中手动添加对应的影射关系,万一写错了。就悲催了。。。。下面反射就出来了,就可以很好解决此问题!

    • 反射getattr处理
    class getfunc():
        def f1(self):
            print("f1")
    
        def f2(self):
            print("f2")
    
    
        def f3(self):
            print("f3")
    
    res = input("请输入url: ")
    
    obj_func = getfunc()
    func = getattr(obj_func,res)
    func()
    
    输出结果:
    
    
    请输入url: f1
    f1
    
    请输入url: f2
    f2
    
    请输入url: f3
    f3
    
    请输入url: f4
    Traceback (most recent call last):
      File "反射.py", line 55, in <module>
        func = getattr(obj_func,res)
    AttributeError: 'getfunc' object has no attribute 'f4'

    这里我们使用的是类的作法,先创建一个类,将所有函数放在类里。在调用前先实例化该类,不论类里有多少个函数,直接根据输入内容通过getattr调用类里的函数。这样后期不管添加多少函数,只要前端能调用符合要求,则都会被调到。
    发现最后一个怎么报错?原来并没有匹配到f4这个函数。反射也提供了检查功能,类似于检查一个字典是否存在某个key一样。下面说明一下反射的基本操作类型

    • 反射的操作类型:
      • getattr() 查找
      • setattr() 设置
      • hasattr() 判断
      • delattr() 删除 接着上面的类说明操作类型的用法:
    class getfunc:
        def __init__(self):
            self.test = '1234'
        def f1(self):
            print("f1")
    
        def f2(self):
            print("f2")
    
    
        def f3(self):
            print("f3")
    
    foo = getfunc()
    print(hasattr(foo,'f1'))    判断是否有f1
    print(hasattr(foo,'f5'))        判断是否有f5
    
    print(setattr(foo,'f5','f1'))   设置f5为f1
    print(getattr(foo,'f5'))    判断是否有f5
    
    print(delattr(foo,'test'))  删除test
    print(hasattr(foo,'test'))   判断是否有test
    
    运行结果:
    True
    False
    None
    f1
    None
    False

    同样模块也支持动态导入,看下面说明:

    • 反射模块

    模块动态导入使用__import__方法

    定义一个模块:fanshe
    def login():
        print('登录页面')
    
    
    def logout():
        print('退出页面')
    
    
    def home():
        print("主页面")
    
    下面是调用代码:
    inp = input("请输入url:")
    m,f = inp.split('/')
    try:
       obj = __import__(m)
    except:
       print("404")
       sys.exit()
    if hasattr(obj,f):
       func = getattr(obj,f)
       func()
    else:
       print("404")
    
    执行结果:
    
    请输入url:fanshe/login
    登录页面
    
    请输入url:fanshe/logout
    退出页面
    
    请输入url:fanshe/home
    主页面

    反射太强大了。

  • 相关阅读:
    Python爬虫学习遇到的问题
    爬取网页内容后写入文件报错UnicodeEncodeError: 'gbk' codec can't encode的问题解决方案
    第14.6节 使用Python urllib.request模拟浏览器访问网页的实现代码
    Mina源码阅读笔记(一)-整体解读
    使用异步 I/O 大大提高应用程序的性能
    同步和异步,阻塞和非阻塞
    位运算详解
    php引用传值详解
    PHP获取指定地区的天气
    新闻网站开发-手机端-基于Wordpress
  • 原文地址:https://www.cnblogs.com/pycode/p/fanshe.html
Copyright © 2011-2022 走看看