前期回顾:
无
本期内容:
一、atm作业讲解二、递归的例子,阶乘三、反射四、模块五、冒泡算法六、本周作业
一、ATM作业讲解
二、递归的例子,阶乘
使用递归实现“1*2*3*4*5*6*7”
#!/usr/bin/env python# -.- coding: utf-8 -.-# By sandler# 递归阶乘def func(num):if num == 1:return 1return num * func(num-1)x = func(7)print(x)
三、反射
利用字符串的形式去对象(模块)中操作(寻找)成员,反射实例:伪造WEB框架的路由系统反射:基于字符串的形式去对象(模块)中操作成员
# 反射的四个方法getattr(commons,input) # 获取hasattr(commons,input) # 检查setattr(commons,input) # 设置delattr(commons,input) # 删除
#!/usr/bin/env python# -.- coding: utf-8 -.-# By sandler# index 反射主程序import commonsdef run():inp = input('请输入要打开页面的URL: ')if hasattr(commons,inp):func = getattr(commons,inp)func()else:print('404')if __name__ == __name__:run()
#!/usr/bin/env python# -.- coding: utf-8 -.-# By sandler# commons index 调用的模块def login():print('登录页面')def logout():print('退出页面')def home():print('主页面')
#!/usr/bin/env python# -.- coding: utf-8 -.-# By sandler# 反射# index.pydef run():inp = input('请输入要打开页面的URL: ')m,f = inp.split('/')obj = __import__(m) # 以字符串格式导入模块if hasattr(obj,f):func = getattr(obj,f)func()else:print('404')if __name__ == __name__:run()
#!/usr/bin/env python# -.- coding: utf-8 -.-# By sandler# commons.pydef login():print('登录页面')def logout():print('退出页面')def home():print('主页面')
#!/usr/bin/env python# -.- coding: utf-8 -.-# By sandler# manager.pydef manager():print('管理页面')
obj = __import__("lib."+m , formlist=True)
扩展:导入模块
import xxxform xxx import oooobj = __import__("xxx")obj = __import__("xxx.ooo.xxx",formlist=True)
四、模块
loggingtime/datetimejson/picklerequests
os
用于提供系统级别的操作:
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cdos.curdir 返回当前目录: ('.')os.pardir 获取当前目录的父目录字符串名:('..')os.makedirs('dir1/dir2') 可生成多层递归目录os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirnameos.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirnameos.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印os.remove() 删除一个文件os.rename("oldname","new") 重命名文件/目录os.stat('path/filename') 获取文件/目录信息os.sep 操作系统特定的路径分隔符,win下为"\",Linux下为"/"os.linesep 当前平台使用的行终止符,win下为" ",Linux下为" "os.pathsep 用于分割文件路径的字符串os.name 字符串指示当前使用平台。win->'nt'; Linux->'posix'os.system("bash command") 运行shell命令,直接显示os.environ 获取系统环境变量os.path.abspath(path) 返回path规范化的绝对路径os.path.split(path) 将path分割成目录和文件名二元组返回os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素os.path.basename(path) 返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素os.path.exists(path) 如果path存在,返回True;如果path不存在,返回Falseos.path.isabs(path) 如果path是绝对路径,返回Trueos.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回Falseos.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回Falseos.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
sys
用于提供对Python解释器相关的操作:
sys.argv 命令行参数List,第一个元素是程序本身路径sys.exit(n) 退出程序,正常退出时exit(0)sys.version 获取Python解释程序的版本信息sys.maxint 最大的Int值sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值sys.platform 返回操作系统平台名称sys.stdin 输入相关sys.stdout 输出相关sys.stderror 错误相关
#!/usr/bin/env python# -.- coding: utf-8 -.-# By sandler# 模块import osimport sysss = os.path.abspath(__file__) # 获取文件的绝对路径dd = os.path.dirname(__file__) # 获取文件的所在目录sys.path.append(os.path.dirname(os.path.abspath(__file__))) # 将文件的目录添加到系统默认路径
hashlib
用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
import hashlib# ######## md5 ########hash = hashlib.md5()# help(hash.update)hash.update(bytes('admin', encoding='utf-8'))print(hash.hexdigest())print(hash.digest())######## sha1 ########hash = hashlib.sha1()hash.update(bytes('admin', encoding='utf-8'))print(hash.hexdigest())# ######## sha256 ########hash = hashlib.sha256()hash.update(bytes('admin', encoding='utf-8'))print(hash.hexdigest())# ######## sha384 ########hash = hashlib.sha384()hash.update(bytes('admin', encoding='utf-8'))print(hash.hexdigest())# ######## sha512 ########hash = hashlib.sha512()hash.update(bytes('admin', encoding='utf-8'))print(hash.hexdigest())
以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。
import hashlib# ######## md5 ########hash = hashlib.md5(bytes('898oaFs09f',encoding="utf-8"))hash.update(bytes('admin',encoding="utf-8"))print(hash.hexdigest())
python内置还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密
import hmach = hmac.new(bytes('898oaFs09f',encoding="utf-8"))h.update(bytes('admin',encoding="utf-8"))print(h.hexdigest())
MD5
#!/usr/bin/env python# -.- coding: utf-8 -.-# By sandler# MD5 加密import hashlibobj = hashlib.md5()obj.update(bytes('123',encoding='utf-8'))result = obj.hexdigest()print(result)
正则表达式
re模块
普通字符:a-z/A-Z/0-9
元字符: . ^ $ * + ? {} [] | ()
字符:. 匹配除换行符以外的任意字符w 匹配字母或数字或下划线或汉字s 匹配任意的空白符d 匹配数字匹配单词的开始或结束^ 匹配字符串的开始$ 匹配字符串的结束次数:* 重复零次或更多次+ 重复一次或更多次? 重复零次或一次{n} 重复n次{n,} 重复n次或更多次{n,m} 重复n到m次
re.findall() # 匹配所有结果
# findall,获取非重复的匹配列表;如果有一个组则以列表形式返回,且每一个匹配均是字符串;如果模型中有多个组,则以列表形式返回,且每一个匹配均是元祖;# 空的匹配也会包含在结果中#findall(pattern, string, flags=0)
# 无分组r = re.findall("aw+",origin)print(r)# 有分组origin = "hello alex bcd abcd lge acd 19"r = re.findall("a((w*)c)(d)", origin)print(r)
re.match() # 从起始位置开始匹配
# match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回Nonematch(pattern, string, flags=0)# pattern: 正则模型# string : 要匹配的字符串# falgs : 匹配模式X VERBOSE Ignore whitespace and comments for nicer looking RE's.I IGNORECASE Perform case-insensitive matching.M MULTILINE "^" matches the beginning of lines (after a newline)as well as the string."$" matches the end of lines (before a newline) as wellas the end of the string.S DOTALL "." matches any character at all, including the newline.A ASCII For string patterns, make w, W, , B, d, Dmatch the corresponding ASCII character categories(rather than the whole Unicode categories, which is thedefault).For bytes patterns, this flag is the only availablebehaviour and needn't be specified.L LOCALE Make w, W, , B, dependent on the current locale.U UNICODE For compatibility only. Ignored for string patterns (itis the default), and forbidden for bytes patterns.
# 无分组r = re.match("hw+", origin)print(r.group()) # 获取匹配到的所有结果print(r.groups()) # 获取模型中匹配到的分组结果print(r.groupdict()) # 获取模型中匹配到的分组结果# 有分组# 为何要有分组?提取匹配成功的指定内容(先匹配成功全部正则,再匹配成功的局部内容提取出来)r = re.match("h(w+).*(?P<name>d)$", origin)print(r.group()) # 获取匹配到的所有结果print(r.groups()) # 获取模型中匹配到的分组结果print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组
re.search() # 匹配一个结果
# search,浏览整个字符串去匹配第一个,未匹配成功返回None# search(pattern, string, flags=0)
# 无分组r = re.search("aw+", origin)print(r.group()) # 获取匹配到的所有结果print(r.groups()) # 获取模型中匹配到的分组结果print(r.groupdict()) # 获取模型中匹配到的分组结果# 有分组r = re.search("a(w+).*(?P<name>d)$", origin)print(r.group()) # 获取匹配到的所有结果print(r.groups()) # 获取模型中匹配到的分组结果print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组
re.sub() # 匹配替换
# sub,替换匹配成功的指定位置字符串sub(pattern, repl, string, count=0, flags=0)# pattern: 正则模型# repl : 要替换的字符串或可执行对象# string : 要匹配的字符串# count : 指定匹配个数# flags : 匹配模式
# 与分组无关origin = "hello alex bcd alex lge alex acd 19"r = re.sub("aw+", "999", origin, 2)print(r)
re.split() # 分割
# split,根据正则匹配分割字符串split(pattern, string, maxsplit=0, flags=0)# pattern: 正则模型# string : 要匹配的字符串# maxsplit:指定分割个数# flags : 匹配模式
# 无分组origin = "hello alex bcd alex lge alex acd 19"r = re.split("alex", origin, 1)print(r)# 有分组origin = "hello alex bcd alex lge alex acd 19"r1 = re.split("(alex)", origin, 1)print(r1)r2 = re.split("(al(ex))", origin, 1)print(r2)
进度条小练习
#!/usr/bin/env python# -.- coding: utf-8 -.-# By sandler# 进度条小程序import sysimport timedef view_bar(num, total):rate = float(num) / float(total)rate_num = int(rate * 100)r = ' %s%d%%' % ("="*num , rate_num)sys.stdout.write(r)sys.stdout.flush()if __name__ == '__main__':for i in range(0, 101):time.sleep(0.1)view_bar(i, 100)
五、冒泡算法

#!/usr/bin/env python# -.- coding: utf-8 -.-# By sandler# 冒泡排序li = [1,5,2,7,11,44,66,33,22]print(li)for i in range(len(li))[::-1]:for j in range(i):if li[j] > li[j+1]:li[j],li[j+1] = li[j+1], li[j]print(li)# 执行结果[1, 5, 2, 7, 11, 44, 66, 33, 22][1, 2, 5, 7, 11, 22, 33, 44, 66]
六、本周作业:
计算器,只处理加减乘除
8*12+(6-(5*6-2)/77+2)*(3-7)+8
# 1、从前到后找,找到第一个 (开始 )结尾,中间不含有括号
# 2、(中间不包含括号)
def 处理加减乘除(表达式):
# 8*12+1*4+8
return 1
def 处理括号(表达式):
while True:
#8*12+(6-(5*6-2)/77+2)*(3-7)+8
re.split("((中间不包含括号))", 表达式, 1)
8*12+(6- 5*6-2 /77+2)*(3-7)+8
ret = 处理加减乘除(5*6-2 )
8*12+(6- ret /77+2)*(3-7)+8
