反射:是利用字符串的形式去对象 (模块) 中操作 (寻找/检查/删除/设置) 成员,以後看其他源碼的時候會經常看到反射,最有代表性的就是 Tornado 和 Django 框架
案例例子
假设创建了一个common.py,程序里有3个功能,比如网站里的登录页面、主页页面和登出页面都是不同的页面,要显示的内容都不一样
def login(): print("Login Page") def logout(): print("Logout Page") def home(): print("HomePage")
再创建一个py程序:index.py,程序一般是写一个判断然后会基于调用不同的功能返回不同的结果(参考调用方法一的代码)。
import common #根据用户不同的输入而返回不同的信息 def run(): inp = input("请输入要访问的 url: ") if inp == "login": # 当用户输入 login,还看到 login 页面 common.login() elif inp == "logout": # 当用户输入 logout,还看到 logout 页面 common.logout() elif inp == "home": # 当用户输入 home,还看到 home 页面 common.home() else: print("404") if __name__ == "__main__": run() index.py 调用方法一
这个时候,就可以运用反射的方法(参考调用方法二的代码),直接基于用户输入,返回需要執行的功能,这样就可以减少判断逻辑代码需要的时间。
反射写法
# 利用字符串的形式去对象 (模块) 中操作 (寻找/检查) 成员 import common def run(): inp = input("请输入要访问的 url: ") is_exists = hasattr(common,inp) # 检查用户输入是否在common模块里存在的一个成员 if is_exists: func = getattr(common, inp) # 到common模块寻找用户输入的一个成员 func() else: print("404") if __name__ == "__main__": run() index.py 调用方法二
运用 hasattr( ) 、 getattr( )、delattr( )、setattr( ) 函数来实现,這几個反射函数分別接收兩個参数(参数一可以是模块, 参数二是参数一的成員 - 它接受一个字符串类型的成员名称),比如说:如果 common 模块里有 login( ) 函数,在调用反射时,基本代码语法是 hasattr(s2,"login")
#s2.py def login(): print("login....") #s1.py import s2 if hasattr(s2,"login"): func = getattr(s2, "login") #接受字符串类型的成员名称 func() """ login.... """
hasattr
(参数一,参数二)
# 到模块里检查成员
#参数一可以是模块, 参数二是参数一的成员
getattr
(参数一,参数二)
# 到模块里寻找成员
#参数一可以是模块, 参数二是参数一的成员
delattr
(参数一,参数二)
# 到模块裡把這個成員删掉
#参数一可以是模块, 参数二是参数一的成员
setattr
(参数一,参数二)
# 到模块裡再设置一個成員
#参数一可以是模块, 参数二是参数一的成员
hasattr
(参数一,参数二)
# 到模块里检查成员
#参数一可以是模块, 参数二是参数一的成员
1
2
|
getattr (参数一,参数二) # 到模块里寻找成员 #参数一可以是模块, 参数二是参数一的成员 |
1
2
|
delattr (参数一,参数二) # 到模块裡把這個成員删掉 #参数一可以是模块, 参数二是参数一的成员 |
1
2
|
setattr (参数一,参数二) # 到模块裡再设置一個成員 #参数一可以是模块, 参数二是参数一的成员 |