date:2018/8/7
1.模块的定义:
模块就是一系列功能的集合体
2.来源:
内置模块
第三方模块
自定义模块
3.模块的格式:
1.使用Python 编写的.py文件
2.已被编译的共享库或DLL的C/C++扩展
3.把一系列模块组织到一起的文件夹
4.使用C编写的链接到python解释中的内置模块
4.为何用模块:
1.使用第三方的模块或者内置:极大提升开发效率
2.使用自定义模块的好处:可以减少代码的冗余
5.如何使用模块: 大前提:一定要区分开执行文件和导入模块
import 模块名
首次导入模块发生的事情:
1. 会产生一个模块的名称空间
2. 执行文件spam.py,将执行过程中产生的名字都放到模块的名称空间中
3. 在当前执行文件的名称空间中拿到一个模块名,该名字指向模块的名称空间
PS:之后的导入,都是直接引用第一次导入的成果,不会重新执行文
总结:在使用时必须加入前缀: 模块名.
优点:指名道姓的向某一个名称空间要名字,与当前名称空间的名字不会冲突
缺点: 但凡应用模块时都需要加前缀,不够简洁
其他用法:
一行导入多个模块 (不推荐使用)
import spam,os,time
可以为模块起别名(注意:模块名应该全为小写
import spam as sm
from ...... import.....
首次导入模块发生的事情:
1. 创建一个模块的名称空间
2. 执行文件spam.py,将执行过程中产生的名字都放到模块的名称空间中
3. 在当前执行文件中直接拿到一个名字,该名字就是执行模块中相对应的名字的
总结from...import...
优点: 使用时,无需再加前缀,更简洁
缺点: 容易与当前名称空间中的名字冲突
其他用法:
*代表从被导入模块中拿到所有名字(不推荐使用)
from spam import*
可以为模块起别名
from spam import read1 as r1
date:2018/8/8
1.模块的循环导入问题:
解决方案一: 把循环导入的语句放到名字定义的后面
解决方案二: 将循环导入语句放到函数内
2.区分python 文件的二种用途:
当文件被执行时__name__=='__main__'
当文件被导入时__name__=='模块名'
3.模块的搜索路径
内存中已经加载过的
内置模块
sys.path # 第一个值是当前执行文件所在的文件夹
注意点:环境变量是以当前执行文件为准的
4.包的相关知识点
定义:就是一个包含有__init__.py文件的文件夹,用来组织文件的
总结其特点:
1. 但凡是在导入语句中带点的,点的左边都必须是一个包
2. 导入包就是在导包下的__init__.py文件
3. 如果使用绝对导入,绝对导入的起始位置都是以包的顶级目录为起始点
4. 但是包内部模块的导入通常应该使用相对导入,用.代表当前所在的文件(而非执行文件),..代表上一级
强调:
1. 相对导入只能包内部的模块之间互相导入使用
2. ..上一级不能超出顶级包
5.绝对导入和相对导入
绝对导入: 以执行文件的sys.path为起始点开始导入,称之为绝对导入
优点: 执行文件与被导入的模块中都可以使用
缺点: 所有导入都是以sys.path为起始点,导入麻烦
相对导入: 参照当前所在文件的文件夹为起始开始查找,称之为相对导入
符号: .代表当前所在文件的文件加,..代表上一级文件夹,...代表上一级的上一级文件夹
优点: 导入更加简单
缺点: 只能在被导入的模块中使用,不能在执行文件中用
6.软件开发的目录规范
以ATM项目为例,建立ATM项目文件夹:
ATM
---Bin 可执行的文件
--- start.py
---conf 配置文件
--- settings.py
---core 核心逻辑
--- src.py
--- db 数据库操作
---lib 自定义模块
--- common.py
---log 关键日志
--- transaction.log
---read me
date:2018/8/9
几种常用模块的介绍
1.time 和datetime模块
time模块
获取时间戳 返回浮点型
print(time.time())
获取当地时间 返回的是结构化时间
print(time.localtime())
获取UTC时间 返回的还是结构化时间 比中国时间少8小时
print(time.gmtime())
将获取的时间转成我们期望的格式 仅支持结构化时间
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
将格式化字符串的时间转为结构化时间 注意 格式必须匹配
print(time.strptime("2018-08-09 09:01:22","%Y-%m-%d %H:%M:%S"))
时间戳 转结构化
print(time.localtime(time.time()))
结构化转 时间戳
print(time.mktime(time.localtime()))
sleep 让当前进程睡眠一段时间 单位是秒
time.sleep(2)
datetime 模块
print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925 print(datetime.date.fromtimestamp(time.time()) ) # 时间戳直接转成日期格式 2016-08-19 print(datetime.datetime.now() ) print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天 print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天 print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时 print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分
2.random模块
print(random.random())#(0,1)----float 大于0且小于1之间的小数
print(random.randint(1,3)) #[1,3] 大于等于1且小于等于3之间的整数
print(random.randrange(1,3)) #[1,3) 大于等于1且小于3之间的整数 print(random.choice([1,'23',[4,5]]))#1或者23或者[4,5]
print(random.sample([1,'23',[4,5]],2))#列表元素任意2个组合 print(random.uniform(1,3))#大于1小于3的小数,如1.927109612082716 item=[1,3,5,7,9] random.shuffle(item) #打乱item的顺序,相当于"洗牌" print(item)
3.os模块
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd os.curdir 返回当前目录: ('.') os.pardir 获取当前目录的父目录字符串名:('..') os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename("oldname","newname") 重命名文件/目录 os.stat('path/filename') 获取文件/目录信息 os.sep 输出操作系统特定的路径分隔符,win下为"\",Linux下为"/" os.linesep 输出当前平台使用的行终止符,win下为" ",Linux下为" " os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为: 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不存在,返回False os.path.isabs(path) 如果path是绝对路径,返回True os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间 os.path.getsize(path) 返回path的大小
os.path.normcase
os.path.normpath(path)规范化路径将路径中所有字符转换为小写,并将所有斜杠转换为饭斜杠。
4.sys模块
sys.argv 命令行参数List,第一个元素是程序本身路径
sys.exit(n) 退出程序,正常退出时exit(0)
sys.version 获取Python解释程序的版本信息
sys.maxint 最大的Int值
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
5.shutil模块
高级的 文件、文件夹、压缩包 处理模块
shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另一个文件中
1 import shutil 2 3 shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
shutil.copyfile(src, dst)
拷贝文件
1 shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在
shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变
1 shutil.copymode('f1.log', 'f2.log') #目标文件必须存在
shutil.copystat(src, dst)
仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
1 shutil.copystat('f1.log', 'f2.log') #目标文件必须存在
shutil.copy(src, dst)
拷贝文件和权限
1 import shutil 2 3 shutil.copy('f1.log', 'f2.log')
shutil.copy2(src, dst)
拷贝文件和状态信息
1 import shutil 2 3 shutil.copy2('f1.log', 'f2.log')
shutil.make_archive(base_name, format,...)
创建压缩包并返回文件路径,例如:zip、tar
创建压缩包并返回文件路径,例如:zip、tar
- base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如 data_bak =>保存至当前路径
如:/tmp/data_bak =>保存至/tmp/ - format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
- root_dir: 要压缩的文件夹路径(默认当前目录)
- owner: 用户,默认当前用户
- group: 组,默认当前组
- logger: 用于记录日志,通常是logging.Logger对象
1 #将 /data 下的文件打包放置当前程序目录 2 import shutil 3 ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data') 4 5 6 #将 /data下的文件打包放置 /tmp/目录 7 import shutil 8 ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
6.pickle和json模块
1. 什么是序列化
序列化指的是将内存中的数据类型转换成一种中间格式,该格式可以用来存到硬盘中或者基于网络传输
2. 为何要序列化
1. 持久化(把某一时刻程序的运行状态永久保存下来)
2. 基于网络传输,可以扩平台交互数据
3. 如何序列化
json:
优点:兼容所有语言,可以扩平台交互数据
缺点:不能支持所有的python数据类型
pickle
优点:可以支持所有的python数据类型
缺点:不能跨平台
json.dumps(数据类型) json.loads(json格式的字符串)
json.dump(数据类型,文件对象) json.load(文件对象)
pickle:
序列化
f = open("p.txt","wb")
f.write(pickle.dumps(users))
f.close()
反序列化
f = open("p.txt","rb")
print(type(pickle.loads(f.read())))
f.close()
序列化
pickle.dump(users,open("pp.txt","wb"))
反序列化
print(pickle.load(open("pp.txt","rb")))
json的序列化
将python格式的数据序列化为json格式 python中的任何类型都能被转化为json格式 表现形式不同
序列化
f = open("p.txt","wt")
f.write(json.dumps(users))
f.close()
反序列化
f = open("p.txt","rb")
print(type(json.loads(f.read())))
f.close()
序列
json.dump(users,open("pp.txt","wt"))
反序列化
print(json.load(open("pp.txt","rt")))
date:2018/8/10
1.logging模块
1. logging 日志的等级:
logging.debug('debug日志') #10
logging.info('info日志') #20
logging.warning('warning 日志')#30
logging.error('error 日志')#40
logging.critical('critical日志')#50
2.logging中的四种对象:
logger对象
filter对象
handler对象
formatter对象
3.logging日志的输出
import os
日志相关的配置
BASE_DIR=os.path.dirname(os.path.dirname(__file__)) #将其环境变量添加到日志的文件夹中
standard_format = '%(asctime)s - task:%(name)s - %(filename)s:%(lineno)d -'
' %(levelname)s : [%(message)s]' # 格式可调整
simple_format = '%(filename)s:%(lineno)d - %(levelname)s : [%(message)s]' # 格式可调整
fh1_path = os.path.join(BASE_DIR,'log','a1.log') # 日志的路径可变
fh2_path = os.path.join(BASE_DIR,'log','a2.log') # 日志的路径可变
log配置字典
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format # 可变量,用来替换格式
},
'simple': {
'format': simple_format # 可变量,用来替换格式
},
},
'filters': {},
'handlers': {
#打印到终端的日志
'ch': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到终端
'formatter': 'simple'
},
#打印到a1.log文件的日志
'fh1': {
'level': 'DEBUG',
'class': 'logging.FileHandler', # 保存到文件
'formatter': 'standard',
'filename': fh1_path, # 日志文件的路径---->可变量
'encoding': 'utf-8',
},
# 打印到a2.log文件的日志
'fh2': {
'level': 'DEBUG',
'class': 'logging.FileHandler', # 保存到文件
'formatter': 'simple',
'filename': fh2_path, # 日志文件的路径--->可变量
'encoding': 'utf-8',
},
},
'loggers': {
'': {
'handlers': ['fh1', 'fh2', 'ch'],
'level': 'DEBUG',
},
},
}
调用该日志时的代码
以下代码存存放于自定义模块 common中
import logging.config # 固定格式
from conf import settings # 调用固定配置格式
def get_logger(name): # name 为日志标题
logging.config.dictConfig(settings.LOGGING_DIC) --->固定格式
logger1=logging.getLogger(name)--->nanem 为日志标题
return logger1
date:2018/8/13
1.shelve模块
定义:也是一种序列化的方式,本质上带有自动化序列的字典,读写的方式和字典一样
具体操作:shelve.open(文件名,)
import shelve
序列化 ------------>必须是双引号 引用
sl = shelve.open("shelvetest.txt")
sl["date"] = "8-13"
sl["list1"] = ["123","456"]
sl.close()
反序列化
s2 = shelve.open("shelvetest.txt")
print(s2.get("list1"))
s2.close()
2.configparser模块
配置文件解析模块
什么是配置文件?
用于提供程序运行所需要的一些信息的文件 后缀 ini cfg
配置文件内容格式
只包括两种元素
section 分区
option 选项
一个文件可以有多个section
一个section可以有多个选项
核心功能
1.sections 获取所有分区
2.options 获取所有选项
3.get 获取一个值 传入 section option
假装做一个下载功能 最大链接速度可以由用户来控制 用户不会看代码 所以提供一个配置文件
import configparser
得到配置文件对象
cfg = configparser.ConfigParser()
读取一个配置文件 >>>>>>>>获取具体明细sections() 或者options()
cfg.read("download.ini")>>>>>>>>>>注意字符编码的设定
print(cfg.sections())
print(cfg.options("section1"))
print(type(cfg.get("section1","maxspeed")))
print(type(cfg.getint("section1","maxspeed")))--->>>>获取某个值的时候 用get()方法
print(cfg.getint("section2","minspeed"))
修改最大速度为2048 >>>>>修改时用set() 和write()方法
cfg.set("section1","maxspeed","2048")
cfg.write(open("download.ini","w",encoding="utf-8"))
3.hashlib 模块
是一种算用于将任意长度的数据,压缩映射到一段固定长度的字符
hash的特点:
1.输入数据不同,得到的hash值有可能相同
2.不能通过hash值来得到输入的值
3.如果算法相同,无论输入的数据长度是多少,得到的hash值长度相同
用途:
常用于加密
加盐的方式:
就是把你加密前的数据做一些改动 例如 把顺序反过来
import hashlib
md = hashlib.md5()
md.update("hello你这么牛逼吗 你破解我试试? DSB".encode("utf-8"))
print(md.hexdigest())
破解MD5可以尝试撞库 原理: 有一个数据库 里面存放了常见的明文和密文的对应关系 ,
所以我可以拿着一个密文取数据库中查找 有没有已经存在的明文 如果有撞库成功 能不能破解凭运气
假设我已经拿到了一个众多账号中的一个密码 我可以那这个密码 挨个测试你的所有账号 可能不能碰到运气
pwd_dic = {"123456":"e10adc3949ba59abbe56e057f20f883e","hello":"5d41402abc4b2a76b9719d911017c592"}
for i in pwd_dic:
if pwd_dic[i] == "5d41402abc4b2a76b9719d911017c592":
print(i)
''
今后我们在写一些需要网络传输的程序时 如果要进行加密 最好把加密的算法搞得更复杂
密码长度为6位
abcdef
在前面加一个 abc 在后面加一个 cba 完事以后在加密
pwd = "abcdef"
pwd = "abc"+pwd+"cba"
md2 = hashlib.md5()
md2.update("121".encode("utf-8"))
md2.update(pwd.encode("utf-8"))
md2.update("akjasjkasa".encode("utf-8"))
print(md2.hexdigest())
加密实际上能做的就是让黑客的的破解成本大于他的利润
sha = hashlib.sha512()
sha.update("abcd".encode("utf-8"))
print(len(sha.hexdigest()))
import hmac
h = hmac.new("121212".encode("utf-8"))
h.update("abcd".encode("utf-8"))
print(h.hexdigest())
4.xml模块
定义:xml 可扩展标记语言
XML语法格式:
标签:被<>包裹以字母开头,可以包含合法字符可以被解析的标记
只有一个根,严格区分大小写,所有的标签都是自定义的,所有标签都必须有结束标签
一、任何的起始标签都必须有一个结束标签。
<tagname></tagname>
<tagname></tagname>
<tagname/> 简化写法
使用场景:
1.配置文件
2.常规的数据交换 例如从服务器获取一段新闻
Elment 表示一个节点
属性
1.text 开始标签和结束标签中间的文本
2.attrib 所有的属性 字典类型
3.tag 标签的名字
方法
get 获取某个属性的值
解析xml
查找
import xml.etree.ElementTree as ET
tree=ET.parse('a.xml')
root=tree.getroot()
三种查找节点的方式
res=root.iter('rank') # 会在整个树中进行查找,而且是查找到所有
for item in res:
print(item)
print('='*50)
print(item.tag) # 标签名
print(item.attrib) #属性
print(item.text) #文本内容
res=root.find('country') # 只能在当前元素的下一级开始查找。并且只找到一个就结束
# print(res.tag)
# print(res.attrib)
# print(res.text)
# cy=root.findall('country') # 只能在当前元素的下一级开始查找,
# print([item.attrib for item in cy])
修改
# import xml.etree.ElementTree as ET
# tree=ET.parse('a.xml')
# root=tree.getroot()
# for year in root.iter('year'):
# year.text=str(int(year.text) + 10)
# year.attrib={'updated':'yes'}
tree.write('b.xml')
tree.write('a.xml')
增加
import xml.etree.ElementTree as ET
tree=ET.parse('a.xml')
root=tree.getroot()
for country in root.iter('country'):
# print(country)
year=country.find('year')
# print(year)
if int(year.text) > 2020:
# print(country.attrib)
# ele=ET.Element('egon')
# ele.attrib={'nb':'yes'}
# ele.text='非常帅'
country.append(ele)
country.remove(year)
tree.write('b.xml')
生成一个XML
import xml.etree.ElementTree as et
创建根标签
root = et.Element("root")
创建节点树
t1 = et.ElementTree(root)
加一个peron标签
persson = et.Element("person")
persson.attrib["name"] = "yyh"
persson.attrib["sex"] = "man"
persson.attrib["age"] = "20"
persson.text = "这是一个person标签"
root.append(persson)
写入文件
t1.write("newXML.xml",encoding="utf-8",xml_declaration=True)
date:2018/8/14
1.re模块
什么是正则表达式
正则表达式是对字符进行处理的逻辑公式,是用特殊字符或者一些特殊字符的组合,
组成一个规则的字符串,这个规则字符串用来表达对字符的过滤逻辑
使用方式:
print(re.findall('w','ab 12+- *&_')) ---->数字,字母,中文以及下划线
print(re.findall('W','ab 12+- *&_'))--->非数字字母中文下划线
print(re.findall('s','ab
1
2 +- *&_'))--->匹配任意空白字符串
print(re.findall('S','ab
1
2 +- *&_'))---->匹配任意非空白字符串
print(re.findall('d','ab
1
2 +- *&_')) ---->匹配任意数字
print(re.findall('D','ab
1
2 +- *&_'))----->匹配任意非数字
print(re.findall('w_sb','egon alex_sb123123wxx_sb,lxx_sb'))
print(re.findall('Aalex','abcalex is salexb'))
# print(re.findall('Aalex','alex is salexb'))
# print(re.findall('^alex','alex is salexb'))---->匹配开头
# print(re.findall('sb','alexsb is sbalexbsb'))
# print(re.findall('sb$','alexsb is sbalexbsb'))--->---->匹配结尾
# print(re.findall('^ebn$','ebn1'))
# print(re.findall('a
c','a
c a c a1c'))
# 重复匹配:
#. ? * + {m,n} .* .*?
#1、.:代表除了换行符外的任意一个字符------>. 号代表除了换行符以外的任意一个字符
# print(re.findall('a.c','abc a1c aAc aaaaaca
c'))
# print(re.findall('a.c','abc a1c aAc aaaaaca
c',re.DOTALL))
#2、?:代表左边那一个字符重复0次或1次-----> ? 代表左边那个字符重复0次或者1次
# print(re.findall('ab?','a ab abb abbb abbbb abbbb')
#3、*:代表左边那一个字符出现0次或无穷次---->* 代表左边那个字符重复0次或者无穷次
# print(re.findall('ab*','a ab abb abbb abbbb abbbb a1bbbbbbb'))
#4、+ :代表左边那一个字符出现1次或无穷次---->+代表左边那个字符重复0次或者无穷次
# print(re.findall('ab+','a ab abb abbb abbbb abbbb a1bbbbbbb'))
#5、{m,n}:代表左边那一个字符出现m次到n次-----> 代表左边那个字符出现的次数
# print(re.findall('ab?','a ab abb abbb abbbb abbbb'))
# print(re.findall('ab{0,1}','a ab abb abbb abbbb abbbb'))
# print(re.findall('ab*','a ab abb abbb abbbb abbbb a1bbbbbbb'))
# print(re.findall('ab{0,}','a ab abb abbb abbbb abbbb a1bbbbbbb'))
# print(re.findall('ab+','a ab abb abbb abbbb abbbb a1bbbbbbb'))
# print(re.findall('ab{1,}','a ab abb abbb abbbb abbbb a1bbbbbbb'))
# print(re.findall('ab{1,3}','a ab abb abbb abbbb abbbb a1bbbbbbb'))
#6、.*:匹配任意长度,任意的字符=====》贪婪匹配
# print(re.findall('a.*c','ac a123c aaaac a *123)()c asdfasfdsadf'))
#7、.*?:非贪婪匹配
# print(re.findall('a.*?c','a123c456c')
# ():分组
# print(re.findall('(alex)_sb','alex_sb asdfsafdafdaalex_sb'))
# print(re.findall(
# 'href="(.*?)"',
# '<li><a id="blog_nav_sitehome" class="menu" href="http://www.cnblogs.com/">博客园</a></li>')
# )
# <li><a id="blog_nav_sitehome" class="menu" href="http://www.cnblogs.com/">博客园</a></li>
# href=".*?"
# []:匹配一个指定范围内的字符(这一个字符来自于括号内定义的)
# print(re.findall('a[0-9][0-9]c','a1c a+c a2c a9c a11c a-c acc aAc'))
#当-需要被当中普通符号匹配时,只能放到[]的最左边或最 右边
# print(re.findall('a[-+*]c','a1c a+c a2c a9c a*c a11c a-c acc aAc'))
# print(re.findall('a[a-zA-Z]c','a1c a+c a2c a9c a*c a11c a-c acc aAc'))
# []内的^代表取反的意思
# print(re.findall('a[^a-zA-Z]c','a c a1c a+c a2c a9c a*c a11c a-c acc aAc'))
# print(re.findall('a[^0-9]c','a c a1c a+c a2c a9c a*c a11c a-c acc aAc'))
# print(re.findall('([a-z]+)_sb','egon alex_sb123123wxxxxxxxxxxxxx_sb,lxx_sb'))
# | :或者
# print(re.findall('compan(ies|y)','Too many companies have gone bankrupt, and the next one is my company'))
# (?:):代表取匹配成功的所有内容,而不仅仅只是括号内的内容
# print(re.findall('compan(?:ies|y)','Too many companies have gone bankrupt, and the next one is my company'))
# print(re.findall('alex|sb','alex sb sadfsadfasdfegon alex sb egon'))
re模块的其他方法:
print(re.findall('alex|sb','123123 alex sb sadfsadfasdfegon alex sb egon'))
print(re.search('alex|sb','123213 alex sb sadfsadfasdfegon alex sb egon').group())---->返回值为None -->只搜索一个
print(re.search('^alex','123213 alex sb sadfsadfasdfegon alex sb egon'))
print(re.search('^alex','alex sb sadfsadfasdfegon alex sb egon').group())
print(re.match('alex','alex sb sadfsadfasdfegon alex sb egon').group())---->只能搜索开头部分
print(re.match('alex','123213 alex sb sadfsadfasdfegon alex sb egon'))
info='a:b:c:d'
print(info.split(':'))
print(re.split(':',info))
info=r'get :a.txt3333/rwx'
print(re.split('[ :\/]',info))
print('egon is beutifull egon'.replace('egon','EGON',1))
print(re.sub('(.*?)(egon)(.*?)(egon)(.*?)',r'123EGON5','123 egon is beutifull egon 123'))
(123 )(egon)( is beutifull )(egon)( 123)
123EGON5
print(re.sub('(lqz)(.*?)(SB)',r'321',r'lqz is SB'))
print(re.sub('([a-zA-Z]+)([^a-zA-Z]+)([a-zA-Z]+)([^a-zA-Z]+)([a-zA-Z]+)',r'52341',r'lqzzzz123+ is SB'))
(lqzzzz)(123+ )(is)( )(SB)
pattern=re.compile('alex')
print(pattern.findall('alex is alex alex'))
print(pattern.findall('alexasdfsadfsadfasdfasdfasfd is alex alex'))
2.subprocess模块
进程: 正在进行中的程序
作用: 用于执行系统命令
常用方法: run () call() Popen()
实例:
import subprocess
print(1)
res = subprocess.run("tasklist",shell=True,stdout=subprocess.PIPE)
print("=====================================================")
print(res.stdout.decode("gbk"))
print(res.stderr)
res = subprocess.call("tasklist",shell=True)
print(res)
第一个进程a读取tasklist的内容 将数据交给另一个进程b 进程b将数据写到文件中
res1 = subprocess.Popen("tasklist",stdout=subprocess.PIPE,shell=True,stderr=subprocess.PIPE)
print("hello")
print(res1.stdout.read().decode("gbk"))
print(res1.stderr.read().decode("gbk"))
res2 = subprocess.Popen("findstr cmd",stdout=subprocess.PIPE,shell=True,stderr=subprocess.PIPE,stdin=res1.stdout)
print(res2.stdout.read().decode("gbk"))