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
    主页面

    反射太强大了。

  • 相关阅读:
    ZOJ 3765 Lights (zju March I)伸展树Splay
    UVA 11922 伸展树Splay 第一题
    UVALive 4794 Sharing Chocolate DP
    ZOJ 3757 Alice and Bod 模拟
    UVALive 3983 捡垃圾的机器人 DP
    UVA 10891 SUM游戏 DP
    poj 1328 Radar Installatio【贪心】
    poj 3264 Balanced Lineup【RMQ-ST查询区间最大最小值之差 +模板应用】
    【转】RMQ-ST算法详解
    poj 3083 Children of the Candy Corn 【条件约束dfs搜索 + bfs搜索】【复习搜索题目一定要看这道题目】
  • 原文地址:https://www.cnblogs.com/pycode/p/fanshe.html
Copyright © 2011-2022 走看看