【python-Day6(反射、正则)】
一、冒泡排序
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
练习:
# 冒泡排序 li = [3,10,5,22,89,55,-4,31] for n in range(1,len(li)): for m in range(len(li)-n): num1 = li[m] num2 = li[m+1] if num1 > num2: temp = li[m] li[m] = num2 li[m+1] = temp print(li) --> [-4, 3, 10, 5, 22, 89, 55, 31]
二、 反射
# 反射:利用字符串的形式去对象(模块)中操作(寻找、删除、设置)成员
# hasattr() getattr() delattr() setattr() --> 都是在内存中操作的
# 场景:伪造web框架的路由系统
练习:
# 模块 commons.py def home(): print("主页面") def login(): print("登录页面") def logout(): print("退出页面") # index.py 导入模块 import commons def run(): inp = input("请输入要访问的URL: ") if inp == "home": commons.home() elif inp == "login": commons.login() elif inp == "logout": commons.logout() else: print("404") if __name__ == '__main__': run()
在上面的代码中使用if语句的话,就是你每写一个方法就得有一个elif语句来判断,假如有1000个方法,这样就得有1000个elif语句。这么看实在是弱爆了。有没有更简单的方法实现字符串参数转换成函数名?那就要使用到反射了。修改后的代码如下:
# 模块 commons.py def home(): print("主页面") def login(): print("登录页面") def logout(): print("退出页面") # index.py 导入模块 import commons def run(): inp = input("请输入要访问的URL: “) # 字符串类型 # 利用字符串的形式去对象(模块)中操作(检查、查找、修改、删除)成员 # delattr()、setattr() 在内存中进行操作 # 通过hasattr()判断函数是否存在 if hasattr(commons, inp): # 通过反射执行commons模块中的函数 func = getattr(commons, inp) func() else: print("404") if __name__ == '__main__': run()
现在只有一个模块,如果有1000个模块,难道要导入1000次?当然不用,我们引入__import__()函数,来实现字符串转换成模块引入。代码如下:
# 模块account.py def login(): print("登录页面") def logout(): print("退出页面") # 模块commons.py def home(): print("主页面") # 模块manager.py def order(): print("订单页面") # 主函数 index.py 导入模块 def run(): # account/login格式 inp = input("请输入要访问的URL: ") m, f = inp.split("/“) # 将account/login格式分割成两部分 m="account",f="login” m,f 都是字符串 obj = __import__(m) # 导入名字为account的模块 # 通过反射实现模块中函数的调用 if hasattr(obj, f): func = getattr(obj, f) func() else: print("404") if __name__ == '__main__': run()
上面的例子其实是伪造了web框架的路由系统。
补充:
__import__("libs.aaa.bbb", fromlist=True) # 支持目录的拼接,否则只能导入libs
如果完整的软件包想要实现更高的可移植性,需要把文件的主目录放到sys.path中,方便模块的导入,方法如下:
def add_path(): # 添加程序的执行路径 import os import sys # ps.path.abspath(__file__) 获取当前执行文件的绝对路径 # os.path.dirname() 获取当前路径的上一层路径 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # 一直找到主目录为止,然后将主目录添加到sys.path # __name__ 只有再执行当前文件时,__name__ =__main__,导入不执行 if __name__ == '__main__': add_path()