目录
- 自定义模块:
- 常用的模块:
- 模块的分类:
- 引用模块发生三件事:
- 引用多个模块:
- py文件的两种功能:
- 寻找一个模块的路径:
- 不同目录加载模块;
- 包的使用:
- 模块使用:
- 序列化模块:
- json模块方法:
- pickle模块:
- sys模块:(路径)
- os模块:(文件,目录)
- hashlib模块:(加密)
- time模块:(时间)
- datetime模块:
- random模块:
- logging模块:
- collections模块:
- re模块:
- subprocess:
自定义模块:
什么是模块:一个.py文件就是模块,节省代码,容易维护,组织结构更清晰
模块的运行方式:
脚本方式:直接用解释器执行,或者pycharm中右键运行。
模块方式:被其他的模块导入,为导入他的模块提供资源(变量,函数定义,)
常用的模块:
json 不同语言之间序列化
pickle pyton语言使用,支持序列化数据类型多
sys 与python解释器交互的,解决变量路径问题
os 文件目录操作,操作系统底层函数
hashlib 加密模块
time 时间模块
datetime 时间模块,查找之前之后时间使用的较多
rendom 取随机值
logging 记录日志
collections 定义特殊的数据类型
re 正则
subprocess 执行windows端命令
模块的分类:
- 内置模块:标准库,python解释器自带的,time,os,sys,等等200多种
- 第三方库(模块):各种大神写的模块,通过pip install...安装的6000多种
- 自己写的模块,自定义模块
引用模块发生三件事:
- 1,import haiyang将haiyang.py文件(变量,函数名)加载到内存
- 2,在内存中创建一个以haiyang命名的名称空间
- 3,通过haiyang.xx名称空间的名字.等方式引用此模块的名字(变量,函数名)
引用多个模块:
- import os
- import sys #引用多个模块时,要逐行引用
import haiyang:
当我引用haiyang模块的时候,实际上将haiyang.py执行一遍,加载到内存 通过import引用的模块,他有自己的独立名称空间,与当前执行文件没有关系。 执行文件:02 模块 import 被引用文件(模块):haiyang.py 为模块起别名: import haiyang as ab print(ab.name)
from haiyang import *:
示例1:被引用文件(模块)all进行限制引用者使用范围
引用者: from haiyang import * 模块: __all__ = ['name'] name = "huhaiyang"
工作中错误示例:
from haiyang import name: from haiyang import * 相当于从haiyang模块的全局空间中将name变量与值得对应关系,复制到当前执行文件的全局空间中 引用模块中的函数,如果此函数修改一些变量,这些变量还是从此模块中寻找,不会改变当前执行文件变量 优点:调用更方便 缺点:引用变量跟当前文件变量冲突
py文件的两种功能:
1.py文件的第一个功能:执行文件(承载代码)脚本,直接打印`__name__`返回`__main__` 2.py文件的第二个功能:模块(被动执行文件),直接打印`__name__`返回模块名 作用:当你在被执行文件中,引用模块后,返回的是模块名,模块中进行了`if __name__ == '__main__':` 判断的话,被执行者是不会执行此函数(控制函数自动调用),模块中可以进行测试代码
寻找一个模块的路径:
- 内存中 >>> 内置模块 >>> sys.path
- 只要这三个地方存在,就可以进行加载这个模块
不同目录加载模块;
将路径加载到sys.path中,以绝对路径导入。
import sys sys.path.append(r'E:\Python-学习\') import haiyang print(haiyang.name)
包的使用:
一个文件其实就是有个包
创建一个包 new-package,会自行创建一个·__init__文件·
创建包过程:
1.将该aaa包内
__init__
.py文件加载到内存2.创建一个以aaa,命名的名称空间
3.通过aaa. 的方式引用
__init__
的所有名字
首先,无论在哪里引用模块,import或者from .. import..
最开始的模块或者包的内存,每只sys,path中能找到的
直接import 为了让我们会使用包里面的
__init__
import 导入包以及包内的功能:
示例1:简单的包引用
bolg |____ aaa | |__ __init__.py #from aaa import m1 | |__ m1.py #定义函数func | |____ run.py #aaa.m1.func() aaa目录文件m1 定义func函数: aaa目录__init__文件中定义:from aaa import m1 import aaa #1.在执行文件写入import aaa #2.aaa的__init__里面写入 from aaa import m1 #3.然后执行aaa.m1.a aaa.m1.func()
示例2:多层目录引用
__init__
#在当前文件中,引用aaa包下的bbb包的变量name #1.在执行文件写入import aaa #2.aaa的__init__里面写入 from aaa import bbb #3.bbb的__init__里面写入一个变量 name ="海洋" #4.然后执行aaa.bbb import aaa print(aaa.bbb.name)
示例3:多层目录引用变量
bolg |____aaa | |__bbb | | |__ __init__.py #相对from ..bbb import m3 或者 from .mb import func3 | | |__ m3.py #func3函数 | | | |__ __init__.py #from aaa import bbb/from aaa import m1 | |__ m1.py #func1函数 | |__ m2.py | |____ run.py #在当前文件中,引用aaa包目录下的bbb包的变量name #1.在执行文件写入import aaa #2.在aaa的__init__里面写入 from aaa import bbb (bbb包里面的__init__里面可以引用) #3.在bbb包的__init__写入 from aaa.bbb import m3 #4.然后执行aaa.bbb.m3.func3() import aaa.bbb aaa.bbb.m3.func3() #调用aaa下bbb下m3 aaa.bbb.func3() #init直接引用func3函数时不用加mb aaa.m1.func1() #调用aaa目录下的m1
from ... import .... 导入包以及包内的功能
这种方式不用设置
__init__
文件# from a.b.c import d.e.f # c的前面必须是个包 # import 的后面一定是名字,并且不能再有点 #第一种直接引用目录文件下的变量 from aaa.bbb.m2 import func1 func1() #第二种直接引用目录下的文件 from aaa.bbb import m2 m2.func1()
模块划整一个包:
# 由于nb模块增加了很多很多功能,所以我们nb这个文件就要划整一个包, # 无论对nb模块有任何操作,对于使用者来说不应该改变,极少的改变对其的调用. bolg |____ nb | |__ __init__.py | |__ m1.py #函数f1,f2 | |__ m2.py #函数f3 | |____ run.py __init__.py存放: from nb.m1 import f1,f2 from nb.m2 import f3 执行文件: run.py 执行:nb.f1() nb.f2() nb.f3()
多层目录引用:
bolg #第一层 |____NB #第二层 | |__dsb #第三层 | | |__ly #f3 | |__ __init__.py | |__ m1.py #f1函数 | |__ m2.py #f2函数 | |____ run.py #__init__存放 from .m1 import f1 from .m2 import f2 from .dsb.ly import f3 #执行文件: #第一种运行方法,将目录添加到sys.path # import sys # sys.path.append(r'E:\相对导入绝对导入\bolg') import NB as nb nb.f1() nb.f2() nb.f3 #第二种运行方法: import dir.NB as nb nb.f1() nb.f2() nb.f3()
模块使用:
序列化模块:
序列化模块:将一种数据结构 (list,dict) 转化成一个特殊的序列(特殊的字符串,bytes)的过程
并且还可以翻转回去。
为什么要有序列化:
- str(list)字符串存储到文件中,读取出来,反转不回去
- 凡是数据通过网络传出去最终格式必须是bytes类型
json模块:
支持python数据结构有限:int str list dict tuple bool none float
pickle模块:
- 支持python中所有的数据类型以及对象,只能是python语言中使用的
shevle模块:
- 只能是文件存取
json模块方法:
dumps序列化: loads 反序列化(主要用于网络传输和多文件存取)
import json dic = {'username':'海洋'} ret = json.dumps(dic) print(ret) ret1 = json.loads(ret) print(ret1) 特殊参数 import json dic = {'username': '海洋', 'password': 123,'status': False} ret = json.dumps(dic,ensure_ascii=False,sort_keys=True) ret1 = json.loads(ret) print(ret,type(ret)) print(ret,type(ret1)) #文件存取: import json dic = {'username': '海洋', 'password': 123,'status': False} with open("jsontest",encoding='utf-8',mode='w') as f1: ret = json.dumps(dic) f1.write(ret) with open("jsontest", encoding='utf-8') as f1: ret2 = json.loads(f1.read()) print(ret2)
多个文件存储使用dumps:
import json dic1 = {'username': '海洋', 'password': 123,'status': False} dic2 = {'username': '俊丽', 'password': 123,'status': False} dic3 = {'username': '宝宝', 'password': 123,'status': False} with open("jsontest",encoding='utf-8',mode='a') as f1: f1.write(f"{json.dumps(dic1)}\n{json.dumps(dic2)}\n{json.dumps(dic3)}\n") with open("jsontest", encoding='utf-8') as f1: for line in f1: ret = json.loads(line) print(ret,type(ret))
dump load:只能用于单个数据的存储文件(不常用 )
#不需要先转换字符串,节省一些代码 import json dic = {'username': '海洋', 'password': 123,'status': False} with open("jsontest",encoding='utf-8',mode='w') as f1: json.dump(dic,f1) with open("jsontest", encoding='utf-8') as f1: dic1 = json.load(f1) print(dic1)
pickle模块:
dumps,loads:(只能是网络传输)
import pickle l1 = ["海洋",'俊丽',888] l2 = pickle.dumps(l1) l3 = pickle.loads(l2) print(l2) print(l3)
dump load:(只能数据结构存取文件)
import pickle l1 = ["海洋",'俊丽',888] with open("jsontest",mode='wb') as f1: pickle.dump(l1,f1) with open("jsontest",mode='rb') as f2: ret = pickle.load(f2) print(ret,type(ret))
dump load:(pickle 多个文件写入)
import pickle l1 = ["海洋",'俊丽',888] l2 = ["海洋",'俊丽',888] l3 = ["海洋",'俊丽',888] with open("jsontest",mode='wb') as f1: pickle.dump(l1,f1) pickle.dump(l2,f1) pickle.dump(l3,f1) with open("jsontest",mode='rb') as f2: ret1 = pickle.load(f2) ret2 = pickle.load(f2) ret3 = pickle.load(f2) print(ret1,ret2,ret3,type(ret1))
pickle 对象写入文件:
#写入 with open(settings.register_student,mode="ab") as f3: pickle.dump(obj_write,f3) #读取 with open(settings.register_student,mode="rb") as f4: while 1: try: ret1 = pickle.load(f4) yield ret1 except Exception: break
sys模块:(路径)
import sys print(sys.path) #获取当前路径 print(sys.version) #获取python版本 1 for i in range(3): print(i) sys.exit() #主动退出 exit() print(111) sys.path.append(路径) #与python解释器进行交互,解决变量路径问题
os模块:(文件,目录)
工作目录:当前目录,父级目录(上层目录)
#操作系统底层函数的方法 import os # 查看当前工作目录和切换目录 print(os.getcwd()) print(os.chdir("路径")) #切换目录,相当于shell的cd print(os.curdir) #返回当前目录名 print(os.pardir) #返回当前目录的父目录字符串名 # 和文件夹相关 os.makedirs("haiyang/haha") #在当前目录生成目录可以生成多层,类似mkdir -p os.removedirs('目录') #若目录为为空则删除,不为空删除不了 os.mkdir('目录') #生成单级目录 os.rmdir('目录') #删除单级空目录,为空无法删除 print(os.listdir('haiyang')) #列出指定目录下的所有文件和子目录,以列表的方式 # 和文件相关 os.remove("file") #删除文件 os.rename('旧文件','新文件') #重命名文件 print(os.stat('jsontest')) #获取文件/目录信息 # path和路径相关 # print(os.path.abspath('jsontest')) #返回当前的绝对路径 #将当前的绝对路径转化为列表,前面为路径,后面为文件名 # print(os.path.split(os.path.abspath('jsontest'))) # print(__file__) #动态获取当前文件的绝对路径 # 获取当前文件的爷爷级目录 # print(os.path.dirname(os.path.abspath('jsontest'))) #获取父级目录 # print(os.path.basename(os.path.abspath('jsontest'))) #返回一个路径最后的文件名 # 判断路径 # os.path.join("路径1",'路径2') #将多个路径拼接组合 # print(os.path.isfile(os.path.abspath('jsontest'))) #判断路径是否是文件 在返回True # print(os.path.isdir(os.path.abspath('jsontest'))) #判断路径是否目录 在返回True # print(os.path.exists(os.path.abspath('jsontest'))) #判断当前路径是否存在 在返回True # print(os.path.isabs(os.path.abspath('jsontest'))) #判断是否是绝对路径 在返回True # print(os.path.getatime('文件或者目录')) #查看文件或者目录最后访问时间 # print(os.path.getmtime('文件或者目录')) #查看文件或者目录最后修改时间 # print(os.path.getsize("文件或者目录")) #查看文件或者目录大小
hashlib模块:(加密)
加密模块,摘要算法,散列算法,等等
加密过程:
- 1,将一个bytes类型的数据,通过hashlib进行加密返回,一个等长度的16进制数字
- 2,过程不可逆
- 3,相同的bytes类型的数据通过相同的加密方法得到的数据绝对相同
- 4,不相同的bytes类型的数据通过相同的加密方法得到的数据也绝对不相同
加密示例:
import hashlib ret = hashlib.md5() ret.update('海洋'.encode('utf-8')) print(ret.hexdigest())
加盐示例:
import hashlib ret = hashlib.md5("俊丽".encode('utf-8')) #俊丽盐 ret.update('海洋'.encode('utf-8')) print(ret.hexdigest())
动态加盐示例:
import hashlib username = input("输入用户名:").strip() password = input('输入密码').strip() ret = hashlib.md5(username.encode('utf-8')) #动态的用户名 ret.update('海洋'.encode('utf-8')) print(ret.hexdigest())
sha系列加密:
#sha系列:安全系数高,耗时高 import hashlib username = input("输入用户名:").strip() password = input('输入密码').strip() ret = hashlib.sha3_512(username.encode('utf-8')) ret.update('海洋'.encode('utf-8')) print(ret.hexdigest())
文件校验:
import hashlib def md5_file(path): ret = hashlib.md5() with open(path,mode='rb') as f1: while 1: content = f1.read(1024) #每次读取文件 if content: ret.update(content) else: return ret.hexdigest() print(md5_file('python-3.7.4rc1-embed-win32.zip'))
time模块:(时间)
三种形式:
- 1,时间戳:time.time() 格林威治时间,时差,计时 1561696705.6334207
- 2,人类看的懂的时间,格式化时间, 2019-6-28 12:00
- 3,结构化时间:python语言使用的,解释器使用的 time.struct_time(tm_year=2019, .....
格式化时间:
#%Y年 %m月 %d日 %H时 %M分 %S秒 print(time.strftime("%Y-%m-%d %H:%M:%S" )) #字符串类型的格式化时间 print(time.strftime("%Y-%m-%d %H:%M:%S %A" )) #字符串类型的格式化时间
时间戳转换格式化时间
timetamp = time.time() st = time.localtime(timetamp) # print(st) time1 = time.strftime('%Y/%m/%d %H:%M:%S',st) print(time1)
格式化时间转化成时间戳
import time ft = time.strftime('%y/%m/%d %H:%M:%S') # print(ft) st = time.strptime(ft,'%y/%m/%d %H:%M:%S') timestamp = time.mktime(st) print(timestamp)
datetime模块:
查找之前的时间:
import datetime time1 = datetime.datetime.now() #现在的时间 print(datetime.datetime.now() + datetime.timedelta(weeks=3)) #三周前 print(current_time.replace(year=1977)) #调整到指定年月
将时间戳转化成时间:
print(datetime.date.fromtimestamp(1232132131))
random模块:
随机取值
import random #随机字符串随机发红包时使用 print(random.random()) #大于0小于1之间的小数 print(random.uniform(1,6)) #随机取1-6的小数 print(random.randint(1,5)) #1-5随机取值 print(random.randrange(1,10,2)) #顾头不顾尾 print(random.choice(['海洋','俊丽','宝宝'])) #可迭代对象随机取列表值 print(random.sample(['海洋','俊丽','宝宝'],2)) #可迭代对象随机取列表值,2选两个 item = [i for i in range(10)] #原列表打乱顺序 random.shuffle(item) print(item)
logging模块:
- 系统日志:记录服务器的一些重要信息,监控系统,网卡流量,记录操作信息等等。
- 网站日志:访问异常,卡顿,网站一些板块,受欢迎程度,访问量,点击率,等等。
- 错误日志:开发人员在开发项目中利用日志进行排错,排除一些避免不了的错误,辅助开发
- 记录用户信息日志:用户的消费习惯,新闻偏好等等(数据库解决)
- 三个版本:
- 1.low版 (简易版)
- 2.标配版(标配版)
- 3.旗舰版(项目中使用的,Django项目)
low版:
#缺点:文件与屏幕输出只能选择一个 import logging logging.basicConfig( #设置级别才会出现info和debug # level=logging.DEBUG, level=30, #设置日志级别,可以调整 format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', #日志格式 filename=r'test.log', #写入日志 ) logging.debug('调试模式') #调试 logging.info('信息信息') #信息 logging.warning('警告信息') #警告 logging.error('错误信息') #错误 logging.critical('严重错误') #关键
标配版:
#文件和屏幕都可以输入 import logging logger = logging.getLogger() #创建一个logger对象 fh = logging.FileHandler('标配版.log',encoding='utf-8') #创建文件对象 sh = logging.StreamHandler() #创建屏幕对象 #创建显示格式: formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s') fh.setFormatter(formatter) #绑定显示格式 sh.setFormatter(formatter) logger.addHandler(fh) #logger对象添加多个fh,ch对象 logger.addHandler(sh) # logger.setLevel(10) #总开关,不写默认级别30,先写总开关 # fh.setLevel(30) # sh.setLevel(10) logging.debug('调试模式') #调试 logging.info('信息信息') #信息 logging.warning('警告信息') #警告 logging.error('错误信息') #错误 logging.critical('严重错误') #关键
旗舰版:
自定制(通过字典的方式)日志
轮转日志的功能
import logging.config #引用配置文件/模块 # 定义三种日志输出格式 开始 standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \ '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字 simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s' #级别/时间/信息 # 定义日志输出格式 结束 #写入日志路径和日志名称 logfile_name = 'log1.log' logfile_path = r"E:\Python-学习\作业\23期\day19-包的导入-login日志\日志\log1.log" # log配置字典 #LOGGING_DIC第一层key不能改变 LOGGING_DIC = { 'version': 1, #版本号 'disable_existing_loggers': False, #固定写法 'formatters': { #日志格式 'standard': { #标准格式 'format': standard_format }, 'simple': { #简单格式 'format': simple_format }, }, 'filters': {}, #过滤 'handlers': { #打印到终端的日志 'sh1': { #终端日志打印到屏幕 'level': 'DEBUG', #debug开始打印 'class': 'logging.StreamHandler', 'formatter': 'simple' }, #打印到文件的日志,收集info及以上的日志 'staff_fh': { #写到文件信息 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件 'formatter': 'standard', # 选择复杂的格式 'filename': logfile_path, # 日志文件 'maxBytes': 3000, # 日志大小字节 5M1024*1024*5 'backupCount': 5, 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, 'boss': { # 写到文件信息 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件 'formatter': 'standard', # 选择复杂的格式 'filename': logfile_path, # 日志文件 'maxBytes': 3000, # 日志大小字节 5M1024*1024*5 'backupCount': 5, 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, }, #句柄 'loggers': { #logging.getLogger(__name__)拿到的logger配置 '': { 'handlers': ['staff_fh', 'sh1','boss'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 'level': 'DEBUG', 'propagate': True, # 向上(更高level的logger)传递 }, }, #产生几个log } def load_my_logging_cfg(task_id): logging.config.dictConfig(LOGGING_DIC) #通过你写的字典方式配置日志/第一步 logger = logging.getLogger(task_id) # 生成一个log实例/ return logger def login(): logging1 = load_my_logging_cfg("登录功能") logging1.info("海洋登录信息") def transfer(): logging2 = load_my_logging_cfg("转账功能") logging2.info("张三给李四转账成功") login() transfer()
旗舰版日志(函数):
import logging.config def student_log(info,task_id): standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \ '[%(levelname)s][%(message)s]' simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' logfile_name = "student_info.log" logfile_path = os.path.join(settings.register_logs,logfile_name) LOGGING_DIC = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': standard_format }, 'simple': { 'format': simple_format }, }, 'filters': {}, 'handlers': { 'staff_fh': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', 'formatter': 'standard', 'filename': logfile_path, 'maxBytes': 3000000, 'backupCount': 5, 'encoding': 'utf-8', }, }, #句柄 'loggers': { '': { 'handlers': ['staff_fh'], 'level': 'DEBUG', 'propagate': True, }, }, } logging.config.dictConfig(LOGGING_DIC) #字典的配置信息 logger = logging.getLogger(task_id) #生成一个log实例 logger.info(info) common.student_log(f"{self.name}创建了课程{ke_name}","创建课程功能") #调用日志
collections模块:
给我们提供一下python数据类型,比较特殊的数据类型,出奇制胜
1.namedtuple: 生成可以使用名字来访问元素内容的tuple(自定义类型)
#命名元祖 from collections import namedtuple Point = namedtuple("point",['x','y']) #"point" 自定义类型 print(type(Point)) p = Point(1,2) #键值对存储 print(type(p)) print(p) print(p[0]) #索引取值
2.deque: 双端队列,类似于列表的一种容器性数据,插入元素,删除元素,效率高
from collections import deque #从后面添加 q = deque(['a',1,'c','d']) q.append('e') print(q) #在前面添加 q.appendleft("66") q.appendleft("77") q.pop() #默认删除最后一个 q.popleft() #默认删除最前面的 print(q) #按照索引删 def q[2] print(q)
3.Counter: 计数器,主要用来计数
from collections import Counter c = Counter("sdagdjashdaskd") print(c)
4.OrderedDict: 有序字典
from collections import OrderedDict od = OrderedDict() od['z'] = 1 od['y'] = 2 od['x'] = 3 print(od.keys())
5.defaultdict 带有默认值的字典
from collections import defaultdict #not in方式 l1 = [11,22,33,44,55,77,88,99] dic = {} for i in l1: if i < 66: if "key1" not in dic: dic['key1'] = [] dic['key1'].append(i) else: if 'key2' not in dic: dic['key2'] = [] dic['key2'].append(i) print(dic) #defaultdict方式 l1 = [11,22,33,44,55,77,88,99] dic = defaultdict(list) for i in l1: if i < 66: dic['key1'].append(i) else: dic['key2'].append(i) print(dic)
re模块:
正则表达式:从字符串中找出你想要的字符串
- 在于对你想要得找个字符串进行一个精确的描述
- 使用在爬虫中
单个字符匹配:
#\W与w #\w 数字字母下划线中文 #\W 非数字字母下划线中文 print(re.findall("\w",'海洋jx 12*() _')) #['海', '洋', 'j', 'x', '1', '2', '_'] print(re.findall("\W",'海洋jx 12*() _')) #[' ', '*', '(', ')', ' '] #\s 空格 换行符 #\S 非空格 换行符 print(re.findall('\s','海洋haiyang*(_ \t \n')) #[' ', '\t', ' ', '\n'] print(re.findall('\S','海洋haiyang*(_ \t \n')) #['海', '洋', 'h', 'a'..... #\d 匹配数字 \d\d匹配两个字符 #\D 匹配非数字 \d\d匹配两个字符 print(re.findall('\d','12345 hai*(_')) #['1', '2', '3', '4', '5'] print(re.findall('\D','12345 hai*(_')) #[' ', 'h', 'a', 'i'..... #\A 匹配以什么开头 # ^ print(re.findall('\Ahello','hello 胡海洋 -_- 666')) #['hello'] print(re.findall('^hello','hello 胡海洋 -_- 666')) #['hello'] # \Z、\$ 匹配以什么结尾 print(re.findall('666\Z','hello 海洋 *-_-* \n666')) #['666'] print(re.findall('666$','hello 海洋 *-_-* \n666')) #['666'] # \n 与 \t 匹配\n 与 \t print(re.findall('\n','hello \n 海洋 \t*-_-*\t \n666')) # ['\n', '\n'] print(re.findall('\t','hello \n 海洋 \t*-_-*\t \n666')) # ['\t', '\t']
元字符匹配:
#. ? * + {m,n} . * .*? #. 匹配任意字符 #如果匹配成功,光标则移动到下一位 #如果为匹配成功,光标向下移动一位 print(re.findall('a.b', 'aabbb,ab aab a*b aaab a海b')) ['aab', 'aab',.... #? 匹配0个或者1个 由左边字符定义的片段,不是ab 就是b(不匹配a) print(re.findall('a?b', 'aabbb,ab aab a*b aabb a海b' )) # * 匹配0个或者多个左边字符表达式。 满足贪婪匹配 print(re.findall('a*b', 'ab aab aaab abbb')) print(re.findall('ab*', 'ab aab aaab abbbbb')) # + 匹配1个或者多个左边字符表达式。 满足贪婪匹配 print(re.findall('a+b', 'ab aab aaab abbb')) # ['ab', 'aab', 'aaab', 'ab'] # {m,n} 匹配m个至n(n能取到)个左边字符表达式。 满足贪婪匹配 print(re.findall('a{2,4}b', 'ab aab aaab aaaaabb')) # ['aab', 'aaab']
贪婪匹配:
#.* 贪婪匹配 从头到尾,必须要a开头b结尾,中间全部匹配,贪婪匹配 #.换行符不匹配 print(re.findall('a.*b', 'ab aab a*()b')) # ['ab aab a*()b'] #换行符也可以匹配 print(re.findall('a.*b', 'ab aab a*()b',re.DOTALL)) # ['ab aab a*()b']
非贪婪匹配:
# .*? 此时的?不是对左边的字符进行0次或者1次的匹配, # 而只是针对.*这种贪婪匹配的模式进行一种限定:告知他要遵从非贪婪匹配 推荐使用! # a到b就匹配也就是0个或者多个 print(re.findall('a.*?b', 'ab a1b a*()b, aaaaaab')) # ['ab', 'a1b', 'a*()b'] # []: 括号中可以放任意一个字符,一个中括号代表一个字符 print(re.findall('[ab]', 'a1b a3b aeb a*b arb a_b')) #匹配里面的a或者b print(re.findall('a[abc]b', 'aab abb acb adb afb a_b')) #匹配前后加[]里面一个 print(re.findall('a[0-9]b', 'a1b a3b aeb a*b arb a_b')) #数字 print(re.findall('a[a-z]b', 'a1b a3b aeb a*b arb a_b')) #小写 print(re.findall('a[a-zA-Z]b', 'aAb aWb aeb a*b arb a_b')) #大小写 print(re.findall('a[0-9][0-9]b', 'a11b a12b a34b a*b arb a_b')) #符合a[][]b里面的两个数字 print(re.findall('a[*-+]b','a-b a*b a+b a/b a6b')) #取符号 #当你想匹配- 时,要把他放在[]里面的最前面 print(re.findall('a[-*$]b','a-b a$b a*b')) #^ 在[]中表示取反的意思. print(re.findall('a[^0-9]b', 'a1b a3b aeb a*b arb a_b'))
分组:
#()分组取 s = 'haiyang_sb junli_sb baobao_sb haha_nb xixi_sb dd_sb' print(re.findall('(\w+)_sb',s)) #|匹配左边或者右边 print(re.findall('haiyang|junli', 'haiyangjunli')) #先把分组去掉筛选,在返回ies和y print(re.findall('compan(y|ies)', 'Too many companies have gone bankrupt, and the next one is my company')) #(?):将全部的内容返回,而不是将组内的内容返回,companies|company道理一样 print(re.findall('compan(?:y|ies)', 'Too many companies have gone bankrupt, and the next one is my company'))
re常用方法:
findall 全部找到以列表返回
print(re.findall('a', 'alexwusirbarryeval')) # ['a', 'a', 'a']
search 找到第一个符合条件的字符串就返回,通过.group()返回
print(re.search('sb|alex', 'alex sb sb barry 日天')) print(re.search('alex', 'alex sb sb barry 日天').group())
match:None,从字符串开头匹配,如果第一个条件字符串符合规则则返回,否则返回none
print(re.match('barry', 'barry alex wusir 日天')) print(re.match('barry', 'barry alex wusir 日天').group())
split 分割 可按照任意分割符进行分割:
print(re.split('[ ::,;;,]','alex wusir,日天,太白;女神;肖锋:吴超'))
sub 替换:
print(re.sub('俊丽', '海洋', '俊丽是最好的'))
自定义obj:
obj=re.compile('\d{2}') print(obj.search('abc123eeee').group()) #12 print(obj.findall('abc123eeee')) #['12'],重用了obj自定义obj:
finditer 迭代器返回
ret = re.finditer('\d', 'ds3sy4784a') #finditer返回一个存放匹配结果的迭代器 print(ret) #
print(next(ret).group()) #查看第一个结果 print(next(ret).group()) #查看第二个结果 print([i.group() for i in ret]) #查看剩余的左右结果
subprocess:
调用示例:
#dir为调用的命令 import subprocess obj = subprocess.Popen('dir', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) print(obj.stdout.read().decode('gbk')) # 正确命令 print('error:',obj.stderr.read().decode('gbk')) # 错误命令