模块讲解----反射 (基于web路由的反射)

一、反射的实际案例:

 1 def main():
 2     menu = ''' 
 3     1、账户信息
 4     2、还款
 5     3、取款
 6     4、转账
 7     5、账单
 8     '''
 9     
10     menu_dic = {
11     '1':account_info,
12     '2':repay,
13     '3':withdraw,
14     '4':transfer,
15     '5':pay_check,
16     }
17     
18     while True:
19     print(menu)
20     user_option = input(">>: ").strip()
21     if user_option in menu_dic:
22         menu_dic[user_option]()
23         

 

反射的总结

1、实例:基于实例来说,就是伪造了web框架的路由系统,即通过一个URL,去定义到某一个模块中的函数上。
2、反射:基于字符串的形式去对象(模块)中,操作其成员。
getattr, delattr,setattr,hasattr
3、扩展:导入模块
import xxx
from xxx import ooo

obj = __import__("xxx")
obj = __import__("xxx.oo.xxx"+m, fromlist=True)

 

 

基础环境:
1、假如有个网页,需要根据用户输入的不同的url路径来展现,不同的页面内容。
2、定义两个模块:commons  index
 
1、commons模块:(模拟不同功能的页面函数)
 1 '''
 2 根据用户输入的url不同,调用不同的函数。
 3 调用不同的函数,返回不同页面的内容。
 4 '''
 5 
 6 
 7 def login():
 8     print('炫酷登录页面')
 9 
10 
11 def logout():
12     print('炫酷退出页面')
13 
14 
15 def home():
16     print('炫酷主页面')

 

 

2、index模块:(判读用户输入url的不同,返回不同的结果)

 1 '''
 2 判断用户输入的url的不同,显示不同的结果
 3 '''
 4 
 5 import commons
 6 
 7 def run():
 8     inp = input('请输入要访问的url>>>')
 9     if inp == 'login':
10         commons.login()
11     elif inp == 'logout':
12         commons.logout()
13     elif inp == 'home':
14         commons.home()
15     else:
16         print('404')
17 
18 
19 if __name__ == '__main__':
20     run()
问题:
1、以上是一个网站的三个函数,也是三个页面功能。
2、现实中,一个网站中有多个页面(成百上千个函数),来处理用户的请求。
3、用户访问很多的页面,访问页面越多,那处理访问请求的函数就不一样。
 
解决方法:
1、在commons模块中要定义好多个页面功能函数,这个不变有多少定义多少。
2、在index中,无需多个if判断,只需要将用户输入的input值,自动匹配commons模块里的函数就OK了。
 
修改方法如下:
inp = input(’请输入要访问的url>>> ‘)
1 #inp获取到的是字符串类型。 inp = “login”
2 #commons.inp()  != commons.login  #回去找inp函数,然后执行
3 #利用字符串的形式去对象(模块)中,去操作(寻找/检查/删除/设置)成员,反射
4 getattr(commons,inp)
5 hasattr(commons,inp)
6 setattr()
7 delattr()

 

反射的使用方法

一、通过反射,寻找/检查模块成员:

 1 import commons
 2 
 3 def run():
 4     inp = input("请输入要访问的url>>>  ")
 5 
 6     #判断模块中的方法是否存在:
 7     if hasattr(commons,inp):   #判读模块内的方法是否存在,如果返回为True则调用。
 8 
 9         #获取模块中包含的成员:getattr(模块名,用户输入的url)
10         func =  getattr(commons,inp)
11         func()
12 
13     else:             #如果返回False则打印错误信息 404。
14         print(404)
15 
16 
17 if __name__ == '__main__':
18     run()

 

二、字符串模式的寻找、导入模块:

1、特点:基于web框架的URL路由模式的反射

2、用途:用户输入的url路径转成字符串的格式,然后调用相应的模块名和方法:
例如:account/login
 
3、分析:该需求分为2部分:
第一部分是:将用户输入的url转成字符串。
第二部分是:利用反射的方式通过字符串调用相应的模块和方法:
 1 def run():
 2     inp = input('请输入要访问的rul>>> ')    #获取url
 3     m,f = inp.split('/')                  #将url转换成字符串
 4     obj = __import__(m)                    #导入字符串中的模块
 5 
 6     if hasattr(obj,f):                    #用内置函数判断字符串中的函数和方法是否存在,
 7         func = getattr(obj,f)              #如果存在,就调用字符串中的模块和方法
 8         func()                            #执行调用方法
 9 
10     else:                                #如果不存在则打印404
11         print(404)
12 
13 
14 if __name__ == '__main__':
15     run()                                 #本地函数调用
16 
17 
18 
19 显示结果:
20 请输入要访问的rul>>> commons/db_mgs
21 炫酷的数据库连接信息:

 

 

三、导入同级文件夹下的模块:

注意:__import__:在默认的时候只导入lib.xx的点前面那个lib模块;
解决方法:需要用字符串拼接("目录名." + 模块名)
                 后参数(fromlist=True)

 

 

1、目录结构:

1 |day6
2 --| index.py
3 -- | lib
4     --| account.py
5     --| manager.py
6     --| commons.py  

 

2、案例:

def run():
    inp = input('请输入url路径>>>')
    m,f = inp.split('/')
    obj = __import__("lib."+m, fromlist=True) 

    if hasattr(obj,f):
      func = getattr(obj,f)
      func()


if __name__ == '__main__':
    run()


显示结果:
请输入url路径>>>manger/order
炫酷的订单页面:

 

 

练习:

 1 #1、定义函数标题:
 2 #登录&注册
 3 login_register = '''
 4     1、登录
 5     2、注册
 6     3、退出
 7 '''
 8 
 9 login_register_dic = {
10     '1':'acc_login',
11     '2':'acc_auth',
12     '3':'quit'
13 }
14 
15 
16 
17 #2、定义函数体
18 def acc_login():
19     print('this is login')
20 
21 
22 def acc_auth():
23     print('This is auth')
24 
25 
26 def quit():
27     print("This is quit")
28 
29 
30 
31 #3、定义反射条件:
32 from core import logger
33 from core import login
34 from core import menu
35 def run():
36    '''
37     被调用的主接口,主要功能如下:
38     1、展示登录注册信息
39     2、通过反射的方式,来实现不同的功能选项,尽量避免过多的if判断
40     '''
41     label = menu.login_register
42     login_reg = menu.login_register_dic
43     flag = False
44     while not flag:
45         print(label)
46         inp = input("请输入编号:").strip()
47         if inp in login_reg:
48             if hasattr(login,login_reg[inp]):
49                 func = getattr(login,login_reg[inp])
50                 func()
51 
52         else:
53             login_log.error("The input number does not exist, please try again !!!")
反射实例

 

posted @ 2017-12-25 16:24  风之岚翔  阅读(447)  评论(0编辑  收藏  举报