反射
说反射之前先介绍一下__import__方法,这个和import导入模块的另一种方式
1. import commons
2. __import__('commons')
如果是多层导入:
1. from list.text import commons
2. __import__(' list.text.commons',fromlist=True) #如果不加上fromlist=True,只会导入list目录
实例:
# lib - commons.py
NAME = 'Maria'
def f1():
return "F1"
def f2():
return "F2"
def f3():
return "F3"
****************************
# index.py
moudle = __import__('lib.commons',fromlist=True)
ret = moudle.f1()
print(ret)
# F1
反射即想到4个内置函数分别为:getattr、hasattr、setattr、delattr 获取成员、检查成员、设置成员、删除成员下面逐一介绍先看例子:
moudle = __import__('lib.commons',fromlist=True)
# 获取成员
ret = getattr(moudle,'f1',None) # 可以设置默认值,没找到时 ret = None
print(ret)
# <function f1 at 0x00000090548CF2F0>
# 获取全局变量:
ret = getattr(dd,"NAME",None)
# 检查成员
ret = hasattr(moudle,'f11') # 因为有f1方法所以返回True
print(ret)
# 设置成员
setattr(moudle,"AGE",18) # 内存中创建了一个全局变量
ret = getattr(moudle,'AGE',None)
print(ret)
setattr(moudle,"ADD",lambda a: a +1 ) # 内存中创建了一个函数
ret = getattr(moudle,'ADD',None)
print(ret(100))
# 删除成员
delattr(moudle,'f3')
ret = hasattr(moudle,'f3')
print(ret)
对于反射小节:
反射: # 根据字符串的形式去某个模块中寻找东西 # 根据字符串的形式去某个模块中判断东西是否存在 # 根据字符串的形式去某个模块中设置东西 # 根据字符串的形式去某个模块中删除东西 # 根据字符串的形式去对象 (某个模块) 中操作成员 结论: 1.根据字符串的形式导入模块。 2.根据字符串的形式去对象(某个模块)中操作其成员
基于反射实现类Web框架的路由系统
实现思路:规定用户输入格式 模块名/函数名 通过__import__的形式导入模块并通过 hasattr和getattr 检查并获取函数返回值。
# lib - commons.py
def login():
return 'login'
def logout():
return 'logout'
********************************
# index.py
target_url = input('请输入url:')
target_module,target_func =target_url.split('/')
moudle = __import__('lib.'+target_module,fromlist=True)
if hasattr(moudle,target_func) == True:
func = getattr(moudle,target_func)
ret = func()
print(ret)
else :
print('404 Not Found!')