1.随机数模块 random
1.随机小数
import random # (0,1)随机取浮点数 random.random() # 0.17988578778011 # (1, 3)取指定范围的浮点数 random.uniform(1,3) # 2.3793286185319555
2.随机整数
import random # [1, 3]随机取整数 random.randint(1, 3) # 1 # [1, 3)随机取整数 random.randrange(1, 3) # 1
3.随机选择返回一个和随机选择返回多个
import random # [可迭代序列]取随机值 random.choice([11, 22, 33]) # 22 # [可迭代序列]取随机2个值,返回的个数为函数的第二个参数 random.sample([11, 22, 33], 2) # [11, 22]
4.打乱列表序列
import random # 随机打乱列表的序列 item = [1, 2, 3, 4, 5] random.shuffle(item) print(item) # [2, 1, 4, 5, 3]
5.其他方法
import random # 以长整型的形式返回用nbit位来表示的随机数 random.getrandbits(nbit) # 生成一个16比特长的随机整数 random.getrandbits(16) # 20962 # 用给定的数a设置随机种子,不给参数a则用当前时间设置随机种子 random.seed(a=None) # 随机数产生与种子有关,如果种子是1,第一个数必定是这个 random.seed(1) # 产生种子1对应的序列 print(random.random()) # 0.13436424411240122 print(random.random()) # 0.8474337369372327 random.seed(1) # 产生种子1对应的序列 print(random.random()) # 0.13436424411240122 print(random.random()) # 0.8474337369372327
6.生成指定长度的随机验证码
import random def v_code(num): code = "" for i in range(num): num = random.randint(0, 9) # alf = chr(random.randint(65, 90)) alf = chr(random.choice([random.randint(65, 90),random.randint(97, 122)])) add = random.choice([num, alf]) code = "".join([code, str(add)]) return code print(v_code(6))
2.与系统相关模块 os
1.os模块概述
os模块是与操作系统交互的一个接口
导入语法: import os
2.文件操作
import os # remove 删除一个文件 os.remove("test1/111") # 删除指定路径的文件,如果指定的路径是一个目录,将抛出异常FileNotFoundError os.unlink("a.txt") # 删除文件,如果文件是一个目录,将抛出异常FileNotFoundError # 递归删除目录和文件夹 for root, dirs, files in os.walk(top, topdown=False): for name in files: os.remove(os.path.join(root, name)) for name in dirs: os.rmdir(os.path.join(root, name)) # 递归遍历目录和文件个数 # dir_count: 不仅会统计一级子文件夹还会统计二级三级子文件夹依次类推一级子文件夹若有一个子文件夹会记作两个 dir_count = 0 # file_count: 不仅会统计文件夹下的文件,还会统计子文件夹下的文件 file_count = 0 for root, dirs, filenames in os.walk(file_path): for dir in dirs: dir_count += 1 for file in filenames: file_count += 1 print("dir_count", dir_count) print("file_count", file_count) # rename 重命名文件/目录 os.rename("test1", "test1")
3.目录操作
import os # getcwd获取当前工作目录,即当前python脚本工作目录路径 print(os.getcwd()) # G:PycharmProjects11_模块lnh_massage # chdir改变当前脚本的工作目录,相当于shell下的cd命令 os.chdir("test1") print(os.getcwd()) # G:PycharmProjects11_模块lnh_massage est1 os.chdir("..") print(os.getcwd()) # G:PycharmProjects11_模块lnh_massage # curdir返回当前目录 print(os.curdir) # . # pardir获取当前父目录字符串名 print(os.pardir) # .. # makedirs 可递归创建文件夹 os.makedirs("makir1/mkdir2") # removedirs 文件夹为空则可递归删除文件夹,知道非空为止 os.removedirs("makir1/mkdir2") # mkdir 生成单级目录 os.mkdir("test2") # rmdir 删除单级空目录,目录不为空则无法删除 os.rmdir("test2") # listdir 列出指定文件下的所有文件和子目录,包含影藏文件,返回一个列表 print(os.listdir("test1")) # stat 获取文件/目录信息 print(os.stat(r"G:PycharmProjects11_模块lnh_massage")) """stat结构 st_mode: inode 保护模式 st_ino: inode 节点号 st_dev: inode 驻留的设备 st_nlink: inode 的链接数 st_uid: 所有者的用户ID st_gid: 所有者的组ID st_size: 普通文件以字节为单位的大小,包含等待某些特殊文件的数据 st_atime: 上次访问的时间 st_mtime: 最后一次修改的时间 st_ctime: 由操作系统报告的"ctime",在某些系统上(如Unix)是最新的元数据更改的时间在其它系统上(如Windows)是创建时间 """
4.系统相关操作
import os # sep 查看操作系统的特定路径分割符 print(os.sep) # Windows为: "",Linux为: "/" # linesep 查看当前平台使用的终止符 print("终止符", os.linesep) # win下" ",linux下" " # pathsep 查看用于分割文件路径的字符串 print("分隔文件", os.pathsep) # win下",",linux下":" # name 以字符串指示查看当前使用平台 print("使用平台", os.name) # win下"nt",linux下"posix" # system 用于运行shell命令 os.system("ping 127.0.0.1") # popen 运行系统命令并返回执行结果,win平台: dir Linux平台: ls, pwd等 r = os.popen("pwd") print(r.read()) # /Users/tangxuecheng # urandom 返回一个指定长度的bytes类型数据 b = os.urandom(5) print(b) # b'xbcxd9xbcxb0xb8'
5.path相关操作
import os # environ 获取系统环境变量 print(os.environ) # path.abspath() 返回规范化的path绝对路径 print(os.path.abspath(r"G:PycharmProjects11_模块lnh_massage est1")) # G:PycharmProjects11_模块lnh_massage est1 # path.split 将path分割成目录和文件名,返回元组 print(os.path.split(r"G:PycharmProjects11_模块lnh_massage est1")) # ('G:\PycharmProjects\11_模块\lnh_massage', 'test1') # path.dirname 返回path.split的第一个元素,目录 print(os.path.dirname(r"G:PycharmProjects11_模块lnh_massage est1")) # G:PycharmProjects11_模块lnh_massage # basename 返回path.split的第二个元素,文件名 print(os.path.basename(r"G:PycharmProjects11_模块lnh_massage est1")) # test1 # path.exists 判断path是否存在,返回布尔值 print(os.path.exists(r"G:PycharmProjects11_模块lnh_massage est1")) # True # path.isabs 判断path是否是绝对路径,返回布尔值 print(os.path.isabs(r"G:PycharmProjects11_模块lnh_massage est1")) # True # path.isfile 判断path是否是一个存在的文件,返回布尔值 print(os.path.isfile(r"G:PycharmProjects11_模块lnh_massage est1")) # False # path.isdir 判断path是否是一个存在的目录 print(os.path.isdir(r"G:PycharmProjects11_模块lnh_massage est1")) # True # path.join 路径拼接,会自动去找当前操作系统的路径分割符拼接 a = r"G:PycharmProjects" b = r"11_模块lnh_massage est1" print(os.path.join(a, b)) # G:PycharmProjects11_模块lnh_massage est1 # path.getatime 返回path所指向的文件或目录最后一次存取时间 print(os.path.getatime(r"G:PycharmProjects11_模块lnh_massage est1")) # 1553962262.1905563 # path.getmtime 返回path所指向的文件或目录最后一次修改时间 print(os.path.getmtime(r"G:PycharmProjects11_模块lnh_massage est1")) # 1553962262.1905563 # path.getsize 返回path所指向的文件的大小,单位为字节 print(os.path.getsize(r"G:PycharmProjects11_模块lnh_massage est1")) # 397
6.进程相关
import os # 创建一个新的进程,返回的pid为新的进程的PID pid = os.fork() # 获取当前进程的PID号 print(os.getpid()) # 10181 # 获取当前进程父进程的PID号 print(os.getppid()) # 10148 # 结束进程,参数是一个整数表示进程的结束状态 print(os._exit(1)) # 等待子进程退出进行处理 p, status = os.wait() # 返回值: 一个二元元组,第一个值为退出的子进程PID,第二个值为子进程退出状态 os.WEXITSTATUS(status) # 获取结束状态原数
3.与解释器相关模块 sys
1.sys模块概述
sys模块是与python解释器交互的一个接口
导入语法: import sys
2.变量
import sys # 模块搜索路径 path[0] 是当前脚本程序的路径名,否则为 '' sys.path """执行结果 ['D:\Program Files (x86)\Scripts\ipython.exe', 'd:\program files (x86)\python37.zip', 'd:\program files (x86)\DLLs', 'd:\program files (x86)\lib', 'd:\program files (x86)', '', 'd:\program files (x86)\lib\site-packages', 'd:\program files (x86)\lib\site-packages\IPython\extensions', 'C:\Users\Administrator\.ipython'] """ # 已加载模块的字典 sys.modules # 版本信息字符串 sys.version # '3.7.7 (default, Mar 10 2020, 15:43:33) [Clang 11.0.0 (clang-1100.0.33.17)]' # 版本信息的命名元组 sys.version_info # sys.version_info(major=3, minor=7, micro=7, releaselevel='final', serial=0) # 操作系统平台名称信息 sys.platform # 'darwin' # 命令行参数 argv[0] 代表当前脚本程序路径名 sys.argv # ['/usr/local/bin/ipython'] # 获得Python版权相关的信息 sys.copyright # 获得Python内建模块的名称(字符串元组) sys.builtin_module_names
3.标准输入输出
import sys # 标准输入文件对象,多用于input() sys.stdin s = sys.stdin.read(10) # 默认从键盘获取 print(s) # 标准输出文件对象,多用于print() sys.stdout s = sys.stdout.write("hello world! ") # hello world! print(s) # 13 # 标准错误输出文件对象,用于输出错误信息 sys.stderr s = sys.stderr.write("错误信息输出 ") # 错误信息输出 print(s) # 7 # 查看 标准输入/输出/错误输出 的文件描述符 print(sys.stdin.fileno()) # 0 print(sys.stdout.fileno()) # 1 print(sys.stderr.fileno()) # 2
4.方法
import sys # 结束一个进程并抛出异常,传入一个正整数表示结束状态 sys.exit() # 不写参数默认为0正常结束 # 传入字符串表示打印进程结束语 sys.exit("end") sys.exit("end") # 得到递归嵌套层次限制(栈的深度) sys.getrecursionlimit() # 3000 # 得到和修改递归嵌套层次限制(栈的深度) sys.setrecursionlimit(n) # 指定字符串加入小数据池 a = sys.intern('hello!@'*20) b = sys.intern('hello!@'*20) print(a is b) # True # 获取文件名: 获取当前位置所在的文件名 print(sys._getframe().f_code.co_filename) # <ipython-input-10-dfaee55b6107> # 获取函数名: 获取当前位置所在的函数名 print(sys._getframe().f_code.co_name) # <module> # 获取行号: 当前位置所在的行号 print(sys._getframe().f_lineno) # 1
5.进度条示例
import sys import time for i in range(100): sys.stdout.write("#") # 向屏幕显示相应的内容 time.sleep(0.1) sys.stdout.flush() # 刷新缓存
6.异常处理和status
import sys try: sys.exit(1) except SystemExit as e: print(e)
4.正则模块 re
1.正则表达式概述
1.正则表达式就是匹配字符串内容的一种规则
2.模块导入语法: import re
3.元字符
. 匹配除换行符以外的任意字符
w 匹配字母或数字或下划线
s 匹配任意的空白符
d 匹配数字
匹配一个换行符
匹配一个制表符
匹配一个单词的结尾
^ 匹配字符串的开始
$ 匹配字符串的结尾
W 匹配非字母或数字或下划线
D 匹配非数字
S 匹配非空白符
a|b 匹配字符a或字符b
() 匹配括号内的表达式,也表示一个组
[...] 匹配字符组中的字符
[^...] 匹配除了字符组中字符的所有字符
4.量词
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
5.贪婪和非贪婪
.* 默认为贪婪匹配模式,会匹配尽量长的字符串
.*? 加上?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串
常用示例:
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
6.分组
() 可以为正则表达式建立一个子组,子组可以看做内部的整体
子组的概述:
1.子组可以改变重复元字符的重复行为,增加子组后对正则表达式整体的匹配内容没有影响
2.子组在某些操作中可以对子组匹配内容单独提取,子组通常不要交叉使用
3.每个正则表达式可以有多个子组,由外到内由左到右依次为第一子组,第二子组
捕获组和非捕获组(命名组和非命名组)
1.子组命名格式: (?Pabc)
2.很多编程接口可以直接通过名字获取子组的匹配内容
3.捕获组中的正则表达式可以通过名字重复调用: (?P=name)
In [43]: import re In [44]: re.search("(ab)+", "ababababab").group() Out[44]: 'ababababab' In [45]: re.search("(?P<dog>ab)cdef(?P=dog)", "abcdefabcde").group() Out[45]: 'abcdefab'
2.普通字符
import re # 匹配相应的普通字符 print(re.findall("coco", "my name is coco hao are you")) # ['coco']
3.元字符: . ^ $ [] | ()
import re # .匹配除了 以外的所有字符,一个点代指1个字符 print(re.findall("m.....e", "my name is coco hao are you")) # ['my name'] # .匹配包括 的所有字符,需要传入第三个参数re.S print(re.findall(".*", "hello world!")) # ['hello', '', 'world!', ''] print(re.findall(".*", "hello world!", re.S)) # ['hello world!', ''] print(re.search(".*", "hello world!").group()) # hello print(re.search(".*", "hello world!", re.S).group()) """ hello world! """ # ^只能在字符串开头匹配内容,表示匹配一个字符串的开始位置 print(re.findall("^m..n", "my name is coco hao are you")) # ['my n'] # $只能在字符串结尾匹配内容,表示匹配一个字符串的结尾位置 print(re.findall("e...u$", "my name is coco hao are you")) # ['e you'] # []字符集,匹配括号范围内的任意一个字符,字符集里的功能符号只有- ^ print(re.findall("x[yz]", "xyaaaxz")) # ['xy', 'xz'] # -范围 print(re.findall("x[a-z]", "xyappxcappxzapp")) # ['xy', 'xc', 'xz'] # ^非 print(re.findall("x[^a-z]", "xyappxcappxzappx1")) # ['x1'] # |管道符-->或,匹配两边任意一个正则表达式符合条件的情况 print(re.findall("ac|b", "123ac566546b")) # ['ac', 'b'] print(re.search(r"^[a-z]{2,8}@(139|163).com$", "xc@139.com").group(1)) # 139 print(re.match(r"[a-z]{2,8}@(139|163).com$", "xuechang@163.com").group(1)) # 163 # ()分组,使用括号可以为正则表达式建立一个子组,子组可以看做内部的整体 print(re.findall("(abc)+", "abc11abc22abc33")) # ['abc', 'abc', 'abc'] # search 如果search中有分组的话,通过group(n)就能够拿到group中的匹配的内容 # 1表示和第一个分组中的值相同 print(re.search(r"<(w*)>(.*)</1>", "<h1>xc@139.com</h1>").group(2)) # xc@139.com # (?P<name>正则表达式) 表示给分组起别名,(?P=name) 表示引用别名为分组匹配到的字符串 ret = re.search("(?P<name>[a-z]+)(?P<age>d+)","coco26echo30").group("name") print(ret) # coco ret = re.search(r"<(?P<h>w*)>(.*)</(?P=h)>", "<h1>xc@139.com</h1>").group("h") print(ret) # h1 # ?:取消分组优先显示 ret= re.findall("www.(baidu|163).com", "aawww.baidu.combb") print(ret) # ['baidu'] ret= re.findall("www.(?:baidu|163).com", "aawww.baidu.combb") print(ret) # ['www.baidu.com'] # 转义元字符 print(re.findall("5*3+2", "5*3+2-10")) # ['5*3+2'] # d: 匹配任意十进制数,相当于[0-9] print(re.findall("d+", "1+(2*3+5-(2-(5-4)))")) # ['1', '2', '3', '5', '2', '5', '4'] # D: 匹配任意非十进制数,相当于[^0-9] print(re.findall("D+", "1+(2*3+5-(2-(5-4)))")) # ['+(', '*', '+', '-(', '-(', '-', ')))'] # s: 匹配任何空白字符,相当于[ fv] print(re.findall("s+", "hello world")) # [' '] # S: 匹配任何非空白字符,相当于[^ fv] print(re.findall("S+", "hello world")) # ['hello', 'world'] # w: 匹配任何字母数字,相当于[a-zA-z0-9_] print(re.findall("w+", "hello world 12345")) # ['hello', 'world', '12345'] # W: 匹配任何非字母数字,相当于[^a-zA-z0-9_] print(re.findall("W+", "hello world 12345")) # [' ', ' '] # : 匹配一个特殊字符边界,如空格 & # 等,r原生字符串:r后面的字符串pythonIDE不解释,交给re解释 print(re.findall(r"lo", "hello hello#hello&")) # ['lo', 'lo', 'lo'] # B: 匹配一个特殊字符非边界,如非空格 非& 非# 等,r原生字符串:r后面的字符串pythonIDE不解释,交给re解释 print(re.findall(r"elB", "hello hello#hello&")) # ['el', 'el', 'el'] # A: 匹配开始位置,相当于^ print(re.findall("Aw+", "hello world 12345")) # ['hello'] # : 匹配结束位置,相当于$ print(re.findall("d+", "hello world 12345")) # ['12345'] # A...: 绝对匹配,以什么开始以什么结束,相当于 ^...$ print(re.findall("A/w+/w+", "/Users/tangxuecheng")) # ['/Users/tangxuecheng']
4.量词: * + ? {}
# *匹配0-无穷次前面的内容 print(re.findall("^d*", "dddddefghddd")) # ['ddddd'] # +匹配1-无穷次的内容 print(re.findall("d+", "dddddefghddd")) # ['ddddd', 'ddd'] # ?匹配0次或者1次的内容 print(re.findall("ghf?", "dddddefghddd")) # ['gh'] # {n}匹配指定重重复n次的内容 print(re.findall("ghd{3}", "dddddefghddd")) # ['ghddd'] # {m,n}匹配指定重复m次到n次的内容 print(re.findall("ghd{0,2}", "dddddefghddd")) # ['ghdd']
5.查找方法: findall, search, match, fullmatch
# findall(pattern, string, flags=0)查找方法: 返回一个列表值为所有匹配上的项 # findall会优先显示分组中的内容,要想取消分组优先(?:正则表达式) ret = re.findall('d+', '19874ashfk01248') print(ret) # ['19874', '01248'] ret1 = re.findall('s+', '19874ashfk01248') print(ret1) # [] # search(pattern, string, flags)查找方法: 匹配一个字符串,匹配到返回math对象,没有匹配到返回None ret = re.search('d+', '@$19874ashfk01248') print(ret) # <re.Match object; span=(2, 7), match='19874'> # 返回的对象通过group来获取匹配到的第一个结果 if ret: print(ret.group()) # 19874 ret = re.search('s+', '19874ashfk01248') # 返回值类型: None 如果没有匹配上就是None print(ret) # None # mach(pattern, string, flags)查找方法: 匹配一个字符串的开头位置,匹配到返回math对象,没有匹配到返回None ret = re.match('d+', '19874ashfk01248') # 同search用法,不同在以字符串开始出进行匹配 print(ret) # <re.Match object; span=(0, 5), match='19874'> ret = re.match("a", "abc").group() print(ret) # a # fullmatch(pattern, string, flags)查找方法: 要求目标字符串完全匹配 ret = re.fullmatch("w+", "abc123") print(ret.group()) # abc123
6.分割和替换方法: split, sub, subn
# split(pattern, string, flags): 按照正则表达式分割字符串方法,遇到分组会保留分组内被切掉的内容 ret = re.split("[ab]", "abcd") # 先按a分割得""和"bcd"再对""和"bcd"按b分割 print(ret) # ['', '', 'cd'] # sub(pattern, replaceStr, string, max, flags): 替换正则表达式匹配到的内容方法,返回替换后的字符串 # 参数一正则表达式,参数二要替换的内容,参数三目标字符串,参数四最多替换几处,参数五为功能标志位 ret = re.sub("d+", "A", "d22d33sd44", 2) print(ret) # dAdAsd44 # subn(pattern, repl, string, count, flags): 替换正则表达式匹配到的内容方法,返回替换后的字符串和实际替换的个数 # 参数一正则表达式,参数二要替换的内容,参数三目标字符串,参数四最多替换几处,参数五为功能标志位 ret = re.subn("d+", "A", "d22d33sd44") print(ret) # ('dAdAsdA', 3)
7.爬虫效率方法: compile
概述: compile编译方法,节省时间:只有在多次使用某一个相同的正则表达式的时候,这个compile才会帮助我们提高程序的效率
语法: obj = re.compile(pattern, flags) # 获取正则表达式对象,参数一是正则表达式,参数二是功能标志位,提供更丰富的匹配
返回对象语法: res = obj.findall(string, pos, endpos) # 通过正则表达式匹配字符串,匹配到的所有结果以列表返回
返回对象语法参数: string: 目标字符串; pos: 目标字符串的匹配开始位置; endpos: 目标字符串的匹配结束位置
import re com = re.compile("d+") ret = com.findall("avc11sss22ssgg33") print(ret) # ['11', '22', '33'] pattern = r"(?P<name1>ab)cd(?P<name2>ab)" # 获取正则表达式compile对象 compile_obj = re.compile(pattern, flags=0) # ########compile对象属性######## # 标志位常量 print(compile_obj.flags) # 32 # 正则表达式 print(compile_obj.pattern) # (?P<name1>ab)cd(?P<name2>ab) # 捕获组字典 print(compile_obj.groupindex) # {'name1': 1, 'name2': 2} # 子组个数 print(compile_obj.groups) # 2 # compile查找方法返回一个match对象 match_obj = compile_obj.search("abcdefabcdabcdefabcde", 6, 15) # ########match对象属性######## # 目标字符串开头位置 print(match_obj.pos) # 6 # 目标字符串结束位置 print(match_obj.endpos) # 15 # 正则表达式对象 print(match_obj.re) # re.compile('(?P<name1>ab)cd(?P<name2>ab)') # 目标字符串 print(match_obj.string) # abcdefabcdabcdefabcde # 分组最后一组名字 print(match_obj.lastgroup) # name2 # 分组最后一组是第几组 print(match_obj.lastindex) # 2 # ########match对象方法######## # 匹配到内容的开始位置 print(match_obj.start()) # 6 # 匹配到内容的结束位置 print(match_obj.end()) # 12 # 匹配到内容的起止位置 print(match_obj.span()) # (6, 12) # 获取match对象匹配的内容,参数默认为0表示获取正则整体的匹配内容 print(match_obj.group()) # abcdab # 参数为大于0的正整数表示获取对应子组匹配内容 print(match_obj.group(1)) # ab # 得到所有子组匹配的内容,元祖形式返回 print(match_obj.groups()) # ('ab', 'ab') # 得到所有捕获组匹配到的内容,字典形式返回 print(match_obj.groupdict()) # {'name1': 'ab', 'name2': 'ab'}
8.爬虫效率方法: finditer
概述: finditer方法处理后返回迭代器, 空间效率: 节省内存
语法: ret = re.finditer(pattern, string, flags) # 使用正则表达式匹配目标内容返回迭代对象,迭代的每个内容为一个math对象
参数: pattern: 正则表达式; string: 目标字符串; flags: 功能标识位
import re ret = re.finditer("d+", "asd22sa33") print(ret) # <callable_iterator object at 0x0000000003548BE0> print(next(ret).group()) # 22 print(next(ret).group()) # 33
9.参数flags
概述: 辅助正则表达式,丰富匹配结果
选项值:
A, ASCII: 匹配ASCII字符
S, DOTALL: 对元字符.起作用,让其可以匹配换行
I, IGNORECASE: 匹配时忽略大小写
L, LOCALE: 影响 “w, “W, “b, “B,做本地化识别(locale-aware)匹配
M, MULTILINE: 可以匹配每一行的开头结尾,影响 ^ 和 $
T, TEMPLATE
U, UNICODE: 根据Unicode字符集解析字符,这个标志影响 w, W, , B
X, VERBOSE: 为正则表达式添加注释
import re res = re.findall("hw+", "Hello World!", re.I) # 忽略大小写 print(res) # ['Hello'] res = re.findall(".+", "Hello World!", re.S) # 忽略大小写 print(res) # ['Hello World!'] s = """hello world! Hello Echo! this is Tom """ res = re.findall("^hw+", s, re.M | re.I) # 可以匹配每一行的开头结尾 print(res) # ['hello', 'hello'] pattern = """(?P<name>hello) # name组 s+ # 空白字符 (world!) # 第二个分组 """ res = re.findall(pattern, s, re.X) # 为正则表达式添加注释 print(res) # [('hello', 'world!')]
10.re模块sub替换方法的高级用法
import re def add(temp): str_num = temp.group() num = int(str_num) + 1 return str(num) ret = re.sub(r"d+", add, "python = 997") print(ret) # python = 998 ret = re.sub(r"d+", add, "python = 99") print(ret) # python = 100 print(getAddress(port))
11.正则匹配接口文档地址示例
1.接口文档文件: 1.txt
RP/0/RSP0/CPU0:2_c-leaf-1# show interfaces Thu Sep 7 15:17:18.514 UTC BVI1 is down, line protocol is down Interface state transitions: 0 Hardware is Bridge-Group Virtual Interface, address is 10f3.116c.e6a7 Internet address is 192.168.100.254/24 MTU 1514 bytes, BW 10000000 Kbit (Max: 10000000 Kbit) reliability 255/255, txload 0/255, rxload 0/255 Encapsulation ARPA, loopback not set, ARP type ARPA, ARP timeout 04:00:00 Last input never, output never Last clearing of "show interface" counters never 5 minute input rate 0 bits/sec, 0 packets/sec 5 minute output rate 0 bits/sec, 0 packets/sec 0 packets input, 0 bytes, 0 total input drops 0 drops for unrecognized upper-level protocol Received 0 broadcast packets, 0 multicast packets 0 packets output, 0 bytes, 0 total output drops Output 0 broadcast packets, 0 multicast packets TenGigE0/0/2/3 is administratively down, line protocol is administratively down Interface state transitions: 0 Hardware is TenGigE, address is 10f3.114b.978f (bia 10f3.114b.978f) Layer 1 Transport Mode is LAN Internet address is Unknown MTU 1514 bytes, BW 10000000 Kbit (Max: 10000000 Kbit) reliability 255/255, txload 0/255, rxload 0/255 Encapsulation ARPA, Full-duplex, 10000Mb/s, SR, link type is force-up output flow control is off, input flow control is off Carrier delay (up) is 10 msec loopback not set, Last input 8w2d, output never Last clearing of "show interface" counters never 5 minute input rate 0 bits/sec, 0 packets/sec 5 minute output rate 0 bits/sec, 0 packets/sec 51 packets input, 3372 bytes, 0 total input drops 0 drops for unrecognized upper-level protocol Received 0 broadcast packets, 51 multicast packets 0 runts, 0 giants, 0 throttles, 0 parity 0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored, 0 abort 0 packets output, 0 bytes, 0 total output drops Output 0 broadcast packets, 0 multicast packets 0 output errors, 0 underruns, 0 applique, 0 resets 0 output buffer failures, 0 output buffers swapped out 0 carrier transitions
2.脚本文件: demo1.py
import re import sys def getAddress(port): pattern = r'^S+' f = open('1.txt', 'r') while True: data = '' for line in f: if line != ' ': data += line else: break if not data: break PORT = re.match(pattern, data).group() if port == PORT: pattern = r'address is (S+)' addr = re.search(pattern, data).group(1) return addr else: continue if __name__ == '__main__': # 运行方式: python3 demo1.py BVI1 port = sys.argv[1] print(getAddress(port))
5.时间相关模块 time
1.time模块概述:
1.time模块常应用于转换时间格式和延时,如果年份小于100会自动转换为加上1900后的值
2.UTC: 国际标准时间,DST: 阳光节约时间,也叫夏令时,夏令修正时间(-1, 0 or 1)
3.导入语法: import time
4.格式化时间字符串:
%y: 两位数的年份表示(00-99)
%Y: 四位数的年份表示(000-9999)
%m: 月份(01-12)
%d: 月内中的一天(0-31)
%H: 24小时制小时数(0-23)
%I: 12小时制小时数(01-12)
%M: 分钟数(00=59)
%S: 秒(00-59)
%a: 本地简化星期名称
%A: 本地完整星期名称
%b: 本地简化的月份名称
%B: 本地完整的月份名称
%c: 本地相应的日期表示和时间表示
%j: 年内的一天(001-366)
%p: 本地A.M.或P.M.的等价符
%U: 一年中的星期数(00-53)星期天为星期的开始
%w: 星期(0-6),星期天为星期的开始,0代表星期一
%W: 一年中的星期数(00-53)星期一为星期的开始
%x: 本地相应的日期表示
%X: 本地相应的时间表示
%Z: 当前时区的名称
%%: %号本身
5.struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,星期几,一年中第几天,是否是夏令时)
索引 | 属性(Attribute) | 值(Values) |
0 | tm_year(年) | 比如2011 |
1 | tm_mon(月) | 1 - 12 |
2 | tm_mday(日) | 1 - 31 |
3 | tm_hour(时) | 0 - 23 |
4 | tm_min(分) | 0 - 59 |
5 | tm_sec(秒) | 0 - 60 |
6 | tm_wday(星期几) | 0 - 6(0表示周一) |
7 | tm_yday(一年中的第几天) | 1 - 366 |
8 | tm_isdst(是否是夏令时) | 默认为0 |
2.模块名.属性
import time # 夏令时时间与UTC时间差(秒为单位) time.altzone # -28800 # 夏令时校正时间 time.daylight # 0 # 本地区时间与UTC时间差(秒为单位) time.timezone # -28800 # 时区名字的元组,第一个名字为未经夏令时修正的时区名,第二个名字为经夏令时修正后的时区名 time.tzname # ('CST', 'CST')
3.模块名.方法-取时间(time, localtime, gmtime)
import time # time()取时间戳-->做计算 print(time.time()) # 1553274079.3324106秒-->1970年凌晨到现在的时间经过了多少秒 # localtime结构化时间-->当地时间 t = time.localtime() # 默认参数time.time() print(t) """执行结果 time.struct_time(tm_year=2020, tm_mon=5, tm_mday=31, tm_hour=11, tm_min=45, tm_sec=51, tm_wday=6, tm_yday=152, tm_isdst=0) """ # 打印年 print(t.tm_year) # 2020 # gmtime结构化时间-->UTC世界标准时间, 比中国时间慢8小时 print(time.gmtime()) # 格林时间 """执行结果 time.struct_time(tm_year=2020, tm_mon=5, tm_mday=31, tm_hour=3, tm_min=48, tm_sec=16, tm_wday=6, tm_yday=152, tm_isdst=0) """
4.模块名.方法-格式转换(localtime, gmtime, mktime, strftime strptime, asctime, ctime)
import time # 时间戳转结构化时间 #time.gmtime(时间戳): UTC时间,与英国伦敦当地时间一致 #time.localtime(时间戳): 当地时间,在北京执行这个方法与UTC时间相差8小时,UTC时间+8小时 = 北京时间 time.gmtime(1500000000) """执行结果 time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=2, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0) """ time.localtime(1500000000) """执行结果 time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=10, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0) """ # mktime结构化时间转换成时间戳 print(time.mktime(t)) time.mktime(time.localtime(15000)) # 15000.0 # strftime结构化时间转换成字符串时间 # Y年 m月 d日 X时分秒 t结构化时间 print(time.strftime("%Y-%m-%d %X", t)) # 2020-05-31 11:45:51 # strptime将字符串时间转换成结构化时间 print(time.strptime("2019:03:23:01:26:11", "%Y:%m:%d:%X")) """print(time.strptime("2019:03:23:01:26:11", "%Y:%m:%d:%X"))执行结果 time.struct_time(tm_year=2019, tm_mon=3, tm_mday=23, tm_hour=1, tm_min=26, tm_sec=11, tm_wday=5, tm_yday=82, tm_isdst=-1) """ # asctime()将结构化时间转换成固定的字符串表达方式-->默认参数取当前结构化时间 # 周月日时分秒年 print(time.asctime()) # Sun May 31 11:52:22 2020 # ctime()将时间戳时间转换成固定的字符串表达方式-->默认参数取当前时间戳 # 周月日时分秒年 print(time.ctime()) # Sun May 31 11:52:48 2020
5.模块名.方法-时间延时(sleep)
import time # sleep()线程推迟指定时间运行,单位秒 time.sleep(1) # 睡一秒
6.模块名.方法-计算时间差(mktime, gmtime)
import time true_time = time.mktime(time.strptime("2017-09-11 08:30:00", "%Y-%m-%d %H:%M:%S")) time_now = time.mktime(time.strptime("2017-09-12 11:00:00", "%Y-%m-%d %H:%M:%S")) dif_time = time_now - true_time struct_time = time.gmtime(dif_time) print("过去了%d年%d月%d天%d小时%d分钟%d秒" % (struct_time.tm_year - 1970, struct_time.tm_mon - 1, struct_time.tm_mday - 1, struct_time.tm_hour, struct_time.tm_min, struct_time.tm_sec))
6.时间相关模块 datetime
1.模块名.方法-取时间(now, utcnow)
from datetime import datetime # 获取当前本地时间 a = datetime.now() print("当前日期:", a) # 当前日期: 2020-06-23 07:13:55.317040 # 获取当前世界时间 b = datetime.utcnow() print("世界时间:", b) # 世界时间: 2020-06-22 23:13:55.317154 # 用指定日期创建datetime类型时间 c = datetime(2018, 5, 27, 16, 30) print("指定日期:", c) # 指定日期: 2018-05-27 16:30:00
2.模块名.方法-类型转换(strptime, strftime)
from datetime import datetime # 字符串转换成datetime类型 d = datetime.strptime("2018/9/30", "%Y/%m/%d") print(d) # 2018-09-30 00:00:00 e = datetime.strptime("2018年9月30日星期六", "%Y年%m月%d日星期六") print(e) # 2018-09-30 00:00:00 f = datetime.strptime("2018年9月30日星期六8时42分24秒", "%Y年%m月%d日星期六%H时%M分%S秒") print(f) # 2018-09-30 08:42:24 g = datetime.strptime("9/30/2018", "%m/%d/%Y") print(g) # 2018-09-30 00:00:00 h = datetime.strptime("9/30/2018 8:42:50 ", "%m/%d/%Y %H:%M:%S ") print(h) # 2018-09-30 08:42:50 # datetime类型转换成字符串 i = datetime(2018, 9, 28, 10, 3, 43) print(i.strftime("%Y年%m月%d日%A,%H时%M分%S秒")) # 2018年09月28日Friday,10时03分43秒 j = datetime(2018, 9, 30, 10, 3, 43) print(j.strftime("%A,%B %d,%Y")) # Sunday,September 30,2018 k = datetime(2018, 9, 30, 9, 22, 17) print(k.strftime("%m/%d/%Y %I:%M:%S%p")) # 09/30/2018 09:22:17AM l = datetime(2018, 9, 30) print(l.strftime("%B %d,%Y")) # September 30,2018
3.模块名.方法-时间截取(strftime)
from datetime import datetime m = datetime.now() # 获取当前系统时间 print(m.strftime("今天是%Y年%m月%d日")) # 今天是2020年06月23日 print(m.strftime("今天是这周的第%w天")) # 今天是这周的第2天 print(m.strftime("今天是今年的第%j天")) # 今天是今年的第175天 print(m.strftime("今周是今年的第%W周")) # 今周是今年的第25周 print(m.strftime("今天是当月的第%d天")) # 今天是当月的第23天
4.时间加减和替换
import datetime print(datetime.datetime.now()) # 2020-06-22 21:08:43.500433 # 时间戳直接转成日期格式 print(datetime.date.fromtimestamp(time.time())) # 2020-06-22 # 返回当前系统时间 print(datetime.datetime.now()) # 2020-06-22 21:08:43.500485 # 当前时间+3天 print(datetime.datetime.now() + datetime.timedelta(3)) # 2020-06-25 21:08:43.500491 # 当前时间-3天 print(datetime.datetime.now() + datetime.timedelta(-3)) # 2020-06-19 21:08:43.500503 # 当前时间+3小时 print(datetime.datetime.now() + datetime.timedelta(hours=3)) # 2020-06-23 00:08:43.500508 # 当前时间+30分 print(datetime.datetime.now() + datetime.timedelta(minutes=30)) # 2020-06-22 21:38:43.500516 # 时间替换 c_time = datetime.datetime.now() print(c_time.replace(minute=3, hour=2)) # 2020-06-22 02:03:43.500522
7.序列化模块 json
1.json模块概述
json用于字符串和Python数据类型间进行转换,set数据类型不能被dump/dumps,json格式中的字符串只能是""
导入语法: import json
2.dump方法和load方法
import json # json格式的key必须是字符串数据类型,如果是数字为key,那么dump之后会强行转成字符串数据类型 dic = {1:2,3:4} str_dic = json.dump(dic) # 转换成所有语言都支持的json的字符串 print(str_dic) # {"1": 2, "3": 4} new_dic = json.load(str_dic) # # 将json处理的字符串还原原来的数据类型 print(new_dic) # {'1': 2, '3': 4} # 单次dump数据到文件里,单次从文件中load出来 f = open('json_file', 'w') dic = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} json.dump(dic, f) # dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件 f.close() f = open('json_file') dic2 = json.load(f) # load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回 f.close() print(type(dic2), dic2) # <class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} # 对列表的dump lst = ['aaa', 123, 'bbb', 12.456] with open('json_demo', 'w') as f: json.dump(lst, f) with open('json_demo') as f: ret = json.load(f) print(ret) # ['aaa', 123, 'bbb', 12.456] # 能不能多次dump数据到文件里,可以多次dump但是不能load出来 dic = {'abc': (1, 2, 3)} lst = ['aaa', 123, 'bbb', 12.456] with open('json_demo', 'w') as f: json.dump(lst, f) json.dump(dic, f) with open('json_demo') as f: ret = json.load(f) # 抛出异常: json.decoder.JSONDecodeError print(ret)
3.dumps方法和loads方法
import json # json对元组做value的字典会把元组强制转换成列表 dic = {'abc':(1,2,3)} str_dic = json.dumps(dic) print(str_dic) # {"abc": [1, 2, 3]} new_dic = json.loads(str_dic) print(new_dic) # {'abc': [1, 2, 3]} # json不支持元组做key操作 dic = {(1,2,3):'abc'} str_dic = json.dumps(dic) # 报错 # 用dumps将多个数据写进入文件 dic = {'abc': (1, 2, 3)} lst = ['aaa', 123, 'bbb', 12.456] with open('json_demo', 'w') as f: str_lst = json.dumps(lst) str_dic = json.dumps(dic) f.write(str_lst + ' ') f.write(str_dic + ' ') with open('json_demo') as f: for line in f: ret = json.loads(line) print(ret) # ['aaa', 123, 'bbb', 12.456] {'abc': [1, 2, 3]} # 序列化: 将一个字典转换成一个字符串,json转换完的字符串类型的字典中的字符串是由""表示的 dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic = json.dumps(dic) print(type(str_dic),str_dic) # <class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"} # 反序列化: 将一个字符串格式的字典转换成一个字典,json处理的字符串类型的字典中的字符串必须由""表示 dic2 = json.loads(str_dic) print(type(dic2),dic2) # <class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} # 处理嵌套的数据类型 list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}] str_dic = json.dumps(list_dic) print(type(str_dic),str_dic) # <class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}] list_dic2 = json.loads(str_dic) print(type(list_dic2),list_dic2) # <class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
4.其他参数说明
Skipkeys
默认值是False,dict的keys内的数据不是python的基本类型(str,unicode,int,long,float,bool,None)
设置为False时,会报TypeError的错误,此时设置成True,则会跳过这类key
ensure_ascii
当它为True的时候,所有非ASCII码字符显示为"uXXXX"序列,只需在dump时将ensure_ascii设置为False即可,
此时存入json的中文即可正常显示
indent
应该是一个非负的整型,如果是0就是顶格分行显示,如果为空就是一行最紧凑显示,否则会换行且按照indent的数值显示前面的空白分行显示,
这样打印出来的json数据也叫pretty-printed json
separators
分隔符,实际上是(item_separator, dict_separator)的一个元组,默认的就是(',', ':'),这表示dictionary内keys之间用','隔开,
而KEY和value之间用':'隔开
sort_keys: 将数据根据keys的值进行排序
import json f = open('file', 'w') json.dump({'国籍': '中国'}, f) ret = json.dumps({'国籍': '中国'}) f.write(ret + ' ') json.dump({'国籍': '美国'},f, ensure_ascii=False) ret = json.dumps({'国籍': '美国'}, ensure_ascii=False) f.write(ret + ' ') f.close()
5.json格式化输出
# 不推荐使用,是为了用户看的更方便,但是会相对浪费存储空间 import json data = {'username': ['汤姆猫', '傻傻的'], 'sex': 'male', 'age': 16} jn_dic = json.dumps(data,sort_keys=True, indent=2, separators=(',', ':'), ensure_ascii=False) print(jn_dic) """执行结果 { "age":16, "sex":"male", "username":[ "汤姆猫", "傻傻的" ] } """
8.序列化模块 pickle
1.pickle模块概述
pickle 用于python特有的类型和python的数据类型间进行转换,对于多次dump/load的操作做了良好的处理
pickle 将数据转换成字节,还支持函数和类的转换,对于对象的序列化需要这个对象对应的类在内存中
pickle 的dump结果是bytes,dump用的f文件句柄需要以wb的形式打开,load所用的f是'rb'模式
导入语法: import pickle
2.dump方法和load方法
# pickle模块来存储每个学员的对象 import pickle with open('pickle_demo','wb') as f: pickle.dump({'k1': 'v1'}, f) pickle.dump({'k11': 'v1'}, f) pickle.dump({'k11': 'v1'}, f) pickle.dump({'k12': [1,2,3]}, f) pickle.dump(['k1','v1','l1'], f) with open('pickle_demo','rb') as f: while True: try: print(pickle.load(f)) except EOFError: break """执行结果 {'k1': 'v1'} {'k11': 'v1'} {'k11': 'v1'} {'k12': [1, 2, 3]} ['k1', 'v1', 'l1'] """ # pickle支持几乎所有对象的 import pickle class Student: def __init__(self, name, age): self.name = name self.age = age Tom = Student('Tom',13) with open('pickle_demo', 'wb') as f: pickle.dump(Tom,f) with open('pickle_demo', 'rb') as f: Cat = pickle.load(f) print(Cat.name) # Tom print(Cat.age) # 13
3.dumps方法和loads方法
import pickle dic1 = {"name": "coco"} data2 = pickle.dumps(dic1) # 转换成所有语言都支持的pickle的bytes print(data2) # b'x80x03}qx00Xx04x00x00x00nameqx01Xx04x00x00x00cocoqx02s.' print(type(data2)) # <class 'bytes'> f1 = open("test3", "wb") # data = pickle.dump(dic1, f) # 直接转化写入文件 f1.write(data2) f1.close() f1_read = open("test3", "rb") data3 = pickle.loads(f1_read.read()) # 将pickle处理的bytes还原原来的数据类型 # data3 = pickle.load(f) # 直接读取还原 print(data3) # {'name': 'coco'} print(type(data3)) # <class 'dict'> f1_read.close()
9.序列化读文件模块 shelve
1.shelve模块概述:
文件改动的比较少,读文件的操作比较多,且大部分读取都需要基于某个key获得某个value时推荐使用shelve模块
导入语法: import shelve
import shelve f = shelve.open(r"shelve.txt") # 生成一个空文本 f["stu1_info"] = {"name": "coco", "age": "26"} # 将字典放入文本 f["stu2_info"] = {"name": "angels", "age": "18"} print(f.get("stu1_info")["name"]) # coco print(f.get("stu2_info")["age"]) # 18 f.close()
10.算法摘要模块 hashlib
import hashlib # md5 # md5是一个算法,32位的字符串,每个字符都是一个十六进制 # md5算法 效率快 算法相对简单 obj = hashlib.md5("ssasdf".encode(encoding="utf8")) # 自定义加盐 obj.update("coco".encode(encoding="utf8")) # 原生md5加密 print(obj.hexdigest()) # 516dacada2fea0112265e3a474dee5fe # sha256 obj = hashlib.sha256("ssasdf".encode(encoding="utf8")) # 自定义加盐 obj.update("coco".encode(encoding="utf8")) # 原生md5加密 print(obj.hexdigest()) # 577cce053410c4bf7ccee892b3d92c55f20c56b773276a326777a4535a021909 # sha1也是一个算法,40位的字符串,每个字符都是一个十六进制 # 算法相对复杂 计算速度也慢 s1 = "fadfasvfdfsf" sha1_obj = hashlib.sha1() sha1_obj.update(s1.encode('utf-8')) res = sha1_obj.hexdigest() print(res,len(res), type(res)) # a794b78d12fd18898d65e1b4ff320f44f7dbe2a9 40 <class 'str'> # 动态加盐 username = input('username : ') passwd = input('password : ') md5obj = hashlib.md5(username.encode('utf-8')) md5obj.update(passwd.encode('utf-8')) print(md5obj.hexdigest()) # ee838c58e5bb3c9e687065edd0ec454f # 文件的一致性校验 md5_obj = hashlib.md5() with open('5.序列化模块_shelve.py', 'rb') as f: md5_obj.update(f.read()) ret1 = md5_obj.hexdigest() md5_obj = hashlib.md5() with open('5.序列化模块_shelve.py.bak', 'rb') as f: md5_obj.update(f.read()) ret2 = md5_obj.hexdigest() print(ret1,ret2) # 大文件的一致性校验 md5_obj = hashlib.md5() with open('5.序列化模块_shelve.py.bak', 'rb') as f: md5_obj.update(f.read(10240)) # 循环 循环的读取文件内容 # 循环的来update print(md5_obj.hexdigest()) # 模拟撞库破解密码 import hashlib passwds = [ 'alex3714', 'alex1313', 'alex94139413', 'alex123456', '123456alex', 'a123lex', ] def make_passwd_dic(passwds): dic = {} for passwd in passwds: m = hashlib.md5() m.update(passwd.encode('utf-8')) dic[passwd] = m.hexdigest() return dic def break_code(cryptograph, passwd_dic): for k, v in passwd_dic.items(): if v == cryptograph: print('密码是===>