Python基础语法文章导航:
- Python基础(01初识数据类型&变量)
- Python基础(02条件&循环语句)
- Python基础(03字符串格式化&运算符&进制&编码)
- Python基础(04 基础练习题)
- Python数据类型(day05整型&布尔类型&字符串类型)
- Python数据类型(06列表&元组)
- Python数据类型(07集合&字典&浮点型&None)
- Python文件操作01(自动化测试文件相关操作)
目录
前言
学习Python文件操作,方便后续自动化测试中对文件的操作处理。
一.XML格式文件
XML格式文件在Python开发中用的相对来说比较少,了解即可。常见的微信支付、微信公众号消息处理时会用到基于xml传输数据。在接口自动化测试中会遇到XML格式的接口交互报文,了解XML格式文件相关操作,对于接口自动化测试用例脚本的编写会有很大的帮助。
1.XML格式文件定义
可扩展标记语言,是一种简单的数据存储语言,XML 被设计用来传输和存储数据。
-
存储,可用来存放配置文件,例如:java的配置文件。
传输,网络传输时以这种格式存在,例如:早期ajax传输的数据、soap协议等。
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2023</year>
<gdppc>141100</gdppc>
<neighbor direction="E" name="Austria" />
<neighbor direction="W" name="Switzerland" />
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2026</year>
<gdppc>59900</gdppc>
<neighbor direction="N" name="Malaysia" />
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2026</year>
<gdppc>13600</gdppc>
<neighbor direction="W" name="Costa Rica" />
<neighbor direction="E" name="Colombia" />
</country>
</data>
2. 读取文件和内容
获取根标签,方法一:
from xml.etree import ElementTree as ET
# ET去打开xml文件
tree = ET.parse("files/xo.xml")
# 获取根标签
root = tree.getroot()
print(root) # <Element 'data' at 0x7f94e02763b0>
获取根标签,方法二:
from xml.etree import ElementTree as ET
content = """
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2023</year>
<gdppc>141100</gdppc>
<neighbor direction="E" name="Austria" />
<neighbor direction="W" name="Switzerland" />
</country>
<country name="Panama">
........
</country>
</data>
"""
root = ET.XML(content)
print(root) # <Element 'data' at 0x7fdaa019cea0>
3.读取节点数据
(1)先利用root = ET.XML(content)获取根节点;再从根节点去找根节点的孩子标签root.find("country");利用XML节点获取节点的tag名字、attrib属性、text内容。
from xml.etree import ElementTree as ET
content = """
<data>
<country name="Liechtenstein" id="999" >
<rank>2</rank>
<year>2023</year>
<gdppc>141100</gdppc>
<neighbor direction="E" name="Austria" />
<neighbor direction="W" name="Switzerland" />
</country>
<country name="Panama">
<rank>69</rank>
<year>2026</year>
<gdppc>13600</gdppc>
<neighbor direction="W" name="Costa Rica" />
<neighbor direction="E" name="Colombia" />
</country>
</data>
"""
# 获取根标签 data
root = ET.XML(content)
country_object = root.find("country")
print(country_object.tag, country_object.attrib)
gdppc_object = country_object.find("gdppc")
print(gdppc_object.tag,gdppc_object.attrib,gdppc_object.text)
#country {'name': 'Liechtenstein', 'id': '999'}
#gdppc {} 141100
(2)可以利用多层for循环获取根节点下面的所有孩子节点。
from xml.etree import ElementTree as ET
content = """
<data>
<country name="Liechtenstein">
<rank>2</rank>
<year>2023</year>
<gdppc>141100</gdppc>
<neighbor direction="E" name="Austria" />
<neighbor direction="W" name="Switzerland" />
</country>
<country name="Panama">
<rank>69</rank>
<year>2026</year>
<gdppc>13600</gdppc>
<neighbor direction="W" name="Costa Rica" />
<neighbor direction="E" name="Colombia" />
</country>
</data>
"""
# 获取根标签 data
root = ET.XML(content)
# 获取data标签的孩子标签
for child in root:
# child.tag = conntry
# child.attrib = {"name":"Liechtenstein"}
print(child.tag, child.attrib)
for node in child:
print(node.tag, node.attrib, node.text)
country {'name': 'Liechtenstein'}
# rank {} 2
# year {} 2023
# gdppc {} 141100
# neighbor {'direction': 'E', 'name': 'Austria'} None
# neighbor {'direction': 'W', 'name': 'Switzerland'} None
# country {'name': 'Panama'}
# rank {} 69
# year {} 2026
# gdppc {} 13600
# neighbor {'direction': 'W', 'name': 'Costa Rica'} None
# neighbor {'direction': 'E', 'name': 'Colombia'} None
(3)获取根节点下面的命名为year的孩子节点的
from xml.etree import ElementTree as ET
content = """
........
"""
root = ET.XML(content)
for child in root.iter('year'):
print(child.tag, child.text)
#year 2023
#year 2026
from xml.etree import ElementTree as ET
content = """
.......
"""
root = ET.XML(content)
v1 = root.findall('country')
print(v1)
v2 = root.find('country').find('rank')
print(v2.text)
#[<Element 'country' at 0x00000225CA8ADA40>, <Element 'country' at 0x00000225CA8ADC20>]
#2
4.修改和删除节点
root = ET.XML(content)
# 修改节点内容和属性
rank = root.find('country').find('rank')
print(rank.text)
rank.text = "999"
rank.set('update', '2020-11-11')
print(rank.text, rank.attrib)
############ 保存文件 ############
tree = ET.ElementTree(root)
tree.write("new.xml", encoding='utf-8')
# 删除节点
root.remove( root.find('country') )
print(root.findall('country'))
############ 保存文件 ############
tree = ET.ElementTree(root)
tree.write("newnew.xml", encoding='utf-8')
#2
#999 {'update': '2020-11-11'}
#[<Element 'country' at 0x000001B57594DC20>]
5.构建文档
(1)生成的XML格式文件
方法一:
<home>
<son name="儿1">
<grandson name="儿11"></grandson>
<grandson name="儿12"></grandson>
</son>
<son name="儿2"></son>
</home>
from xml.etree import ElementTree as ET
# 创建根标签
root = ET.Element("home")
# 创建节点大儿子
son1 = ET.Element('son', {'name': '儿1'})
# 创建小儿子
son2 = ET.Element('son', {"name": '儿2'})
# 在大儿子中创建两个孙子
grandson1 = ET.Element('grandson', {'name': '儿11'})
grandson2 = ET.Element('grandson', {'name': '儿12'})
son1.append(grandson1)
son1.append(grandson2)
# 把儿子添加到根节点中
root.append(son1)
root.append(son2)
tree = ET.ElementTree(root)
tree.write('oooo.xml', encoding='utf-8', short_empty_elements=False)
方法二:
<famliy>
<son name="儿1">
<grandson name="儿11"></grandson>
<grandson name="儿12"></grandson>
</son>
<son name="儿2"></son>
</famliy>
from xml.etree import ElementTree as ET
# 创建根节点
root = ET.Element("famliy")
# 创建大儿子
son1 = root.makeelement('son', {'name': '儿1'})
# 创建小儿子
son2 = root.makeelement('son', {"name": '儿2'})
# 在大儿子中创建两个孙子
grandson1 = son1.makeelement('grandson', {'name': '儿11'})
grandson2 = son1.makeelement('grandson', {'name': '儿12'})
son1.append(grandson1)
son1.append(grandson2)
# 把儿子添加到根节点中
root.append(son1)
root.append(son2)
tree = ET.ElementTree(root)
tree.write('oooo.xml',encoding='utf-8')
方法三:
<famliy>
<son name="儿1">
<age name="儿11">孙子</age>
</son>
<son name="儿2"></son>
</famliy>
from xml.etree import ElementTree as ET
# 创建根节点
root = ET.Element("famliy")
# 创建节点大儿子d
son1 = ET.SubElement(root, "son", attrib={'name': '儿1'})
# 创建小儿子
son2 = ET.SubElement(root, "son", attrib={"name": "儿2"})
# 在大儿子中创建一个孙子
grandson1 = ET.SubElement(son1, "age", attrib={'name': '儿11'})
grandson1.d = '孙子'
et = ET.ElementTree(root) #生成文档对象
et.write("test.xml", encoding="utf-8")
(2)XML格式的文件编程JSON格式的文件
content = """<xml>
<ToUserName><![CDATA[gh_7f083739789a]]></ToUserName>
<FromUserName><![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8]]></FromUserName>
<CreateTime>1395658920</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[TEMPLATESENDJOBFINISH]]></Event>
<MsgID>200163836</MsgID>
<Status><![CDATA[success]]></Status>
</xml>"""
from xml.etree import ElementTree as ET
info = {}
root = ET.XML(content)
for node in root:
# print(node.tag,node.text)
info[node.tag] = node.text
print(info)
二.Excel格式文件
Python内部未提供处理Excel文件的功能,想要在Python中操作Excel需要按照第三方的模块。
pip install openpyxl
1.读Excel
(1)读sheet
from openpyxl import load_workbook
wb = load_workbook("files/p1.xlsx")
# sheet相关操作
# 1.获取excel文件中的所有sheet名称
print(wb.sheetnames) # ['数据导出', '用户列表', 'Sheet1', 'Sheet2']
# 2.选择sheet,基于sheet名称
sheet = wb["数据导出"]
cell = sheet.cell(1, 2)
print(cell.value)
# 3.选择sheet,基于索引位置
sheet = wb.worksheets[0]
cell = sheet.cell(1,2)
print(cell.value)
# 4.循环所有的sheet
for name in wb.sheetnames:
sheet = wb[name]
cell = sheet.cell(1, 1)
print(cell.value)
for sheet in wb.worksheets:
cell = sheet.cell(1, 1)
print(cell.value)
for sheet in wb:
cell = sheet.cell(1, 1)
print(cell.value)
(2)读sheet中单元格的数据
from openpyxl import load_workbook
wb = load_workbook("files/p1.xlsx")
sheet = wb.worksheets[0]
# 1.获取第N行第N列的单元格(位置是从1开始)
"""
cell = sheet.cell(1, 1)
print(cell.value)
print(cell.style)
print(cell.font)
print(cell.alignment)
"""
# 2.获取某个单元格
"""
c1 = sheet["A2"]
print(c1.value)
c2 = sheet['D4']
print(c2.value)
"""
# 3.第N行所有的单元格
"""
for cell in sheet[1]:
print(cell.value)
"""
# 4.所有行的数据(获取某一列数据)
"""
for row in sheet.rows:
print(row[0].value, row[1].value)
"""
# 5.获取所有列的数据
"""
for col in sheet.columns:
print(col[1].value)
"""
(3)读合并的单元格
from openpyxl import load_workbook
wb = load_workbook("files/p1.xlsx")
sheet = wb.worksheets[2]
# 获取第N行第N列的单元格(位置是从1开始)
c1 = sheet.cell(1, 1)
print(c1) # <Cell 'Sheet1'.A1>
print(c1.value) # 用户信息
c2 = sheet.cell(1, 2)
print(c2) # <MergedCell 'Sheet1'.B1>
print(c2.value) # None
from openpyxl import load_workbook
wb = load_workbook('files/p1.xlsx')
sheet = wb.worksheets[2]
for row in sheet.rows:
print(row)
>>> 输出结果
(<Cell 'Sheet1'.A1>, <MergedCell 'Sheet1'.B1>, <Cell 'Sheet1'.C1>)
(<Cell 'Sheet1'.A2>, <Cell 'Sheet1'.B2>, <Cell 'Sheet1'.C2>)
(<Cell 'Sheet1'.A3>, <Cell 'Sheet1'.B3>, <Cell 'Sheet1'.C3>)
(<MergedCell 'Sheet1'.A4>, <Cell 'Sheet1'.B4>, <Cell 'Sheet1'.C4>)
(<Cell 'Sheet1'.A5>, <Cell 'Sheet1'.B5>, <Cell 'Sheet1'.C5>)
2.写Excel
在Excel中想要写文件,大致要分为在:
原Excel文件基础上写内容。
from openpyxl import load_workbook
wb = load_workbook('files/p1.xlsx')
sheet = wb.worksheets[0]
# 找到单元格,并修改单元格的内容
cell = sheet.cell(1, 1)
cell.value = "新的开始"
# 将excel文件保存到p2.xlsx文件中
wb.save("files/p2.xlsx")
新创建Excel文件写内容。
from openpyxl import workbook
# 创建excel且默认会创建一个sheet(名称为Sheet)
wb = workbook.Workbook()
sheet = wb.worksheets[0] # 或 sheet = wb["Sheet"]
# 找到单元格,并修改单元格的内容
cell = sheet.cell(1, 1)
cell.value = "新的开始"
# 将excel文件保存到p2.xlsx文件中
wb.save("files/p2.xlsx")
在了解了如何读取Excel和创建Excel之后,后续对于Excel中的sheet和cell操作基本上都相同。
from openpyxl import workbook
wb = workbook.Workbook() # Sheet
# 1. 修改sheet名称
"""
sheet = wb.worksheets[0]
sheet.title = "数据集"
wb.save("p2.xlsx")
"""
# 2. 创建sheet并设置sheet颜色
"""
sheet = wb.create_sheet("工作计划", 0)
sheet.sheet_properties.tabColor = "1072BA"
wb.save("p2.xlsx")
"""
# 3. 默认打开的sheet
"""
wb.active = 0
wb.save("p2.xlsx")
"""
# 4. 拷贝sheet
"""
sheet = wb.create_sheet("工作计划")
sheet.sheet_properties.tabColor = "1072BA"
new_sheet = wb.copy_worksheet(wb["Sheet"])
new_sheet.title = "新的计划"
wb.save("p2.xlsx")
"""
# 5.删除sheet
"""
del wb["用户列表"]
wb.save('files/p2.xlsx')
"""
from openpyxl import load_workbook
from openpyxl.styles import Alignment, Border, Side, Font, PatternFill, GradientFill
wb = load_workbook('files/p1.xlsx')
sheet = wb.worksheets[1]
# 1. 获取某个单元格,修改值
"""
cell = sheet.cell(1, 1)
cell.value = "开始"
wb.save("p2.xlsx")
"""
# 2. 获取某个单元格,修改值
"""
sheet["B3"] = "Alex"
wb.save("p2.xlsx")
"""
# 3. 获取某些单元格,修改值
"""
cell_list = sheet["B2":"C3"]
for row in cell_list:
for cell in row:
cell.value = "新的值"
wb.save("p2.xlsx")
"""
# 4. 对齐方式
"""
cell = sheet.cell(1, 1)
# horizontal,水平方向对齐方式:"general", "left", "center", "right", "fill", "justify", "centerContinuous", "distributed"
# vertical,垂直方向对齐方式:"top", "center", "bottom", "justify", "distributed"
# text_rotation,旋转角度。
# wrap_text,是否自动换行。
cell.alignment = Alignment(horizontal='center', vertical='distributed', text_rotation=45, wrap_text=True)
wb.save("p2.xlsx")
"""
# 5. 边框
# side的style有如下:dashDot','dashDotDot', 'dashed','dotted','double','hair', 'medium', 'mediumDashDot', 'mediumDashDotDot','mediumDashed', 'slantDashDot', 'thick', 'thin'
"""
cell = sheet.cell(9, 2)
cell.border = Border(
top=Side(style="thin", color="FFB6C1"),
bottom=Side(style="dashed", color="FFB6C1"),
left=Side(style="dashed", color="FFB6C1"),
right=Side(style="dashed", color="9932CC"),
diagonal=Side(style="thin", color="483D8B"), # 对角线
diagonalUp=True, # 左下 ~ 右上
diagonalDown=True # 左上 ~ 右下
)
wb.save("p2.xlsx")
"""
# 6.字体
"""
cell = sheet.cell(5, 1)
cell.font = Font(name="微软雅黑", size=45, color="ff0000", underline="single")
wb.save("p2.xlsx")
"""
# 7.背景色
"""
cell = sheet.cell(5, 3)
cell.fill = PatternFill("solid", fgColor="99ccff")
wb.save("p2.xlsx")
"""
# 8.渐变背景色
"""
cell = sheet.cell(5, 5)
cell.fill = GradientFill("linear", stop=("FFFFFF", "99ccff", "000000"))
wb.save("p2.xlsx")
"""
# 9.宽高(索引从1开始)
"""
sheet.row_dimensions[1].height = 50
sheet.column_dimensions["E"].width = 100
wb.save("p2.xlsx")
"""
# 10.合并单元格
"""
sheet.merge_cells("B2:D8")
sheet.merge_cells(start_row=15, start_column=3, end_row=18, end_column=8)
wb.save("p2.xlsx")
"""
"""
sheet.unmerge_cells("B2:D8")
wb.save("p2.xlsx")
"""
# 11.写入公式
"""
sheet = wb.worksheets[3]
sheet["D1"] = "合计"
sheet["D2"] = "=B2*C2"
wb.save("p2.xlsx")
"""
"""
sheet = wb.worksheets[3]
sheet["D3"] = "=SUM(B3,C3)"
wb.save("p2.xlsx")
"""
# 12.删除
"""
# idx,要删除的索引位置
# amount,从索引位置开始要删除的个数(默认为1)
sheet.delete_rows(idx=1, amount=20)
sheet.delete_cols(idx=1, amount=3)
wb.save("p2.xlsx")
"""
# 13.插入
"""
sheet.insert_rows(idx=5, amount=10)
sheet.insert_cols(idx=3, amount=2)
wb.save("p2.xlsx")
"""
# 14.循环写内容
"""
sheet = wb["Sheet"]
cell_range = sheet['A1:C2']
for row in cell_range:
for cell in row:
cell.value = "xx"
for row in sheet.iter_rows(min_row=5, min_col=1, max_col=7, max_row=10):
for cell in row:
cell.value = "oo"
wb.save("p2.xlsx")
"""
# 15.移动
"""
# 将H2:J10范围的数据,向右移动15个位置、向上移动1个位置
sheet.move_range("H2:J10",rows=1, cols=15)
wb.save("p2.xlsx")
"""
"""
sheet = wb.worksheets[3]
sheet["D1"] = "合计"
sheet["D2"] = "=B2*C2"
sheet["D3"] = "=SUM(B3,C3)"
sheet.move_range("B1:D3",cols=10, translate=True) # 自动翻译公式
wb.save("p2.xlsx")
"""
# 16.打印区域
"""
sheet.print_area = "A1:D200"
wb.save("p2.xlsx")
"""
# 17.打印时,每个页面的固定表头
"""
sheet.print_title_cols = "A:D"
sheet.print_title_rows = "1:3"
wb.save("p2.xlsx")
"""
三.压缩文件
基于Python内置的shutil模块可以实现对压缩文件的操作。
import shutil
# 1. 压缩文件
"""
# base_name,压缩后的压缩包文件
# format,压缩的格式,例如:"zip", "tar", "gztar", "bztar", or "xztar".
# root_dir,要压缩的文件夹路径
"""
# shutil.make_archive(base_name=r'datafile',format='zip',root_dir=r'files')
# 2. 解压文件
"""
# filename,要解压的压缩包文件
# extract_dir,解压的路径
# format,压缩文件格式
"""
# shutil.unpack_archive(filename=r'datafile.zip', extract_dir=r'xxxxxx/xo', format='zip')
四.路径相关
1.转义
windows路径使用的是\,linux路径使用的是/。
特别的,在windows系统中如果有这样的一个路径
D:\nxxx\txxx\x1
,程序会报错。因为在路径中存在特殊符\n
(换行符)和\t
(制表符),Python解释器无法自动区分。所以,在windows中编写路径时,一般有两种方式:
加转义符,例如:
"D:\\nxxx\\txxx\\x1"
路径前加r,例如:
r"D:\\nxxx\\txxx\\x1"
2.程序当前路径
项目中如果使用了相对路径,那么一定要注意当前所在的位置。
例如:在
/Users/wupeiqi/PycharmProjects/CodeRepository/
路径下编写demo.py
文件with open("a1.txt", mode='w', encoding='utf-8') as f: f.write("你好呀")
用以下两种方式去运行:
方式1,文件会创建在
/Users/wupeiqi/PycharmProjects/CodeRepository/
目录下。cd /Users/wupeiqi/PycharmProjects/CodeRepository/ python demo.py方式2,文件会创建在
/Users/wupeiqi
目录下。cd /Users/wupeiqi python /Users/wupeiqi/PycharmProjects/CodeRepository/demo.py
3.文件和路径相关
import shutil
import os
# 1. 获取当前脚本绝对路径
"""
abs_path = os.path.abspath(__file__)
print(abs_path)
"""
# 2. 获取当前文件的上级目录
"""
base_path = os.path.dirname( os.path.dirname(路径) )
print(base_path)
"""
# 3. 路径拼接
"""
p1 = os.path.join(base_path, 'xx')
print(p1)
p2 = os.path.join(base_path, 'xx', 'oo', 'a1.png')
print(p2)
"""
# 4. 判断路径是否存在
"""
exists = os.path.exists(p1)
print(exists)
"""
# 5. 创建文件夹
"""
os.makedirs(路径)
"""
"""
path = os.path.join(base_path, 'xx', 'oo', 'uuuu')
if not os.path.exists(path):
os.makedirs(path)
"""
# 6. 是否是文件夹
"""
file_path = os.path.join(base_path, 'xx', 'oo', 'uuuu.png')
is_dir = os.path.isdir(file_path)
print(is_dir) # False
folder_path = os.path.join(base_path, 'xx', 'oo', 'uuuu')
is_dir = os.path.isdir(folder_path)
print(is_dir) # True
"""
# 7. 删除文件或文件夹
"""
os.remove("文件路径")
"""
"""
path = os.path.join(base_path, 'xx')
shutil.rmtree(path)
"""
# 8. 拷贝文件夹
"""
shutil.copytree("/Users/wupeiqi/Desktop/图/csdn/","/Users/wupeiqi/PycharmProjects/CodeRepository/files")
"""
# 9.拷贝文件
"""
shutil.copy("/Users/wupeiqi/Desktop/图/csdn/WX20201123-112406@2x.png","/Users/wupeiqi/PycharmProjects/CodeRepository/")
shutil.copy("/Users/wupeiqi/Desktop/图/csdn/WX20201123-112406@2x.png","/Users/wupeiqi/PycharmProjects/CodeRepository/x.png")
"""
# 10.文件或文件夹重命名
"""
shutil.move("/Users/wupeiqi/PycharmProjects/CodeRepository/x.png","/Users/wupeiqi/PycharmProjects/CodeRepository/xxxx.png")
shutil.move("/Users/wupeiqi/PycharmProjects/CodeRepository/files","/Users/wupeiqi/PycharmProjects/CodeRepository/images")
"""
总结:
主要围绕着文件
相关的操作来展开进行讲解,让大家能够基于Python处理不同格式的文件。由于涉及的知识点比较多,所以今日的内容学起来会比较耗时,但都比较简单,只需要理解并编写好相关笔记以便后期开发时翻阅即可。