tongsiying

阅读|运动|自律

0%

第21篇:文件操作扩展篇

学习目标

了解常见的csvexcelini文件的相关操作,熟悉文件压缩的方法,掌握路径相关的概念和操作。不要求记住每一种文件的具体操作方法,但要做好笔记,以备将来查阅。

一、CSV文件

1. CSV文件介绍

CSV(Comma Separated Values)全称逗号分隔值文件是一种简单、通用的文件格式,被广泛的应用于应用程序(数据库、电子表格等)数据的导入和导出以及异构系统之间的数据交换。因为CSV是纯文本文件,不管是什么操作系统和编程语言都是可以处理纯文本的,而且很多编程语言中都提供了对读写CSV文件的支持,因此CSV格式在数据处理和数据科学中被广泛应用。

CSV文件有以下特点:

  1. 纯文本,使用某种字符集(如ASCIIUnicodeGB2312)等);
  2. 由一条条的记录组成(典型的是每行一条记录);
  3. 每条记录被分隔符(如逗号、分号、制表符等)分隔为字段(列);
  4. 每条记录都有同样的字段序列。

CSV文件可以使用文本编辑器或类似于Excel电子表格这类工具打开和编辑,当使用Excel这类电子表格打开CSV文件时,你甚至感觉不到CSV和Excel文件的区别。很多数据库系统都支持将数据导出到CSV文件中,当然也支持从CSV文件中读入数据保存到数据库中,这些内容并不是我们这里讨论的重点。

2. 将数据写入CSV文件

现有五个学生三门课程的考试成绩需要保存到一个CSV文件中,要达成这个目标,可以使用Python标准库中的csv模块,该模块的writer函数会返回一个csvwriter对象,通过该对象的writerowwriterows方法就可以将数据写入到CSV文件中,具体的代码如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
import csv
import random

with open('scores.csv', 'w') as file:
writer = csv.writer(file)
writer.writerow(['姓名', '语文', '数学', '英语'])
names = ['关羽', '张飞', '赵云', '马超', '黄忠']
for i in range(5):
verbal = random.randint(50, 100)
math = random.randint(40, 100)
english = random.randint(30, 100)
writer.writerow([names[i], verbal, math, english])

需要说明的是上面的writer函数,该函数除了传入要写入数据的文件对象外,还可以dialect参数,它表示CSV文件的方言,默认值是excel。除此之外,还可以通过delimiterquotecharquoting参数来指定分隔符(默认是逗号)、包围值的字符(默认是双引号)以及包围的方式。其中,包围值的字符主要用于当字段中有特殊符号时,通过添加包围值的字符可以避免二义性。大家可以尝试将上面第5行代码修改为下面的代码,看看生成的CSV文件到底有什么区别。

1
writer = csv.writer(file, delimiter='|', quoting=csv.QUOTE_ALL)

3. 从CSV文件读取数据

如果要读取刚才创建的CSV文件,可以使用下面的代码,通过csv模块的reader函数可以创建出csvreader对象,该对象是一个迭代器,可以通过next函数或for-in循环读取到文件中的数据。

1
2
3
4
5
6
7
8
9
import csv

with open('scores.csv', 'r') as file:
reader = csv.reader(file, delimiter='|')
for line in reader:
print(reader.line_num, end='\t')
for elem in line:
print(elem, end='\t')
print()

注意:上面的代码对csvreader对象做for循环时,每次会取出一个列表对象,该列表对象包含了一行中所有的字段。

4. 练习题案例

当然,利用上一节学过的Python的内置文件读写函数也可以完成对csv文件的读写操作,请看下面的示例。

要求:下载文档中的所有图片且以用户名为图片名称存储。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
ID,用户名,头像
26044585,Hush,https://hbimg.huabanimg.com/51d46dc32abe7ac7f83b94c67bb88cacc46869954f478-aP4Q3V
19318369,柒十一,https://hbimg.huabanimg.com/703fdb063bdc37b11033ef794f9b3a7adfa01fd21a6d1-wTFbnO
15529690,Law344,https://hbimg.huabanimg.com/b438d8c61ed2abf50ca94e00f257ca7a223e3b364b471-xrzoQd
18311394,Jennah·,https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz
18009711,可洛爱画画,https://hbimg.huabanimg.com/03331ef39b5c7687f5cc47dbcbafd974403c962ae88ce-Co8AUI
30574436,花姑凉~,https://hbimg.huabanimg.com/2f5b657edb9497ff8c41132e18000edb082d158c2404-8rYHbw
17740339,小巫師,https://hbimg.huabanimg.com/dbc6fd49f1915545cc42c1a1492a418dbaebd2c21bb9-9aDqgl
18741964,桐末tonmo,https://hbimg.huabanimg.com/b60cee303f62aaa592292f45a1ed8d5be9873b2ed5c-gAJehO
30535005,TANGZHIQI,https://hbimg.huabanimg.com/bbd08ee168d54665bf9b07899a5c4a4d6bc1eb8af77a4-8Gz3K1
31078743,你的老杨,https://hbimg.huabanimg.com/c46fbc3c9a01db37b8e786cbd7174bbd475e4cda220f4-F1u7MX
25519376,尺尺寸,https://hbimg.huabanimg.com/ee29ee198efb98f970e3dc2b24c40d89bfb6f911126b6-KGvKes
21113978,C-CLong,https://hbimg.huabanimg.com/7fa6b2a0d570e67246b34840a87d57c16a875dba9100-SXsSeY
24674102,szaa,https://hbimg.huabanimg.com/0716687b0df93e8c3a8e0925b6d2e4135449cd27597c4-gWdv24
30508507,爱起床的小灰灰,https://hbimg.huabanimg.com/4eafdbfa21b2f300a7becd8863f948e5e92ef789b5a5-1ozTKq
12593664,yokozen,https://hbimg.huabanimg.com/cd07bbaf052b752ed5c287602404ea719d7dd8161321b-cJtHss
16899164,一阵疯,https://hbimg.huabanimg.com/0940b557b28892658c3bcaf52f5ba8dc8402100e130b2-G966Uz
847937,卩丬My㊊伴er彎,https://hbimg.huabanimg.com/e2d6bb5bc8498c6f607492a8f96164aa2366b104e7a-kWaH68
31010628,慢慢即漫漫,https://hbimg.huabanimg.com/c4fb6718907a22f202e8dd14d52f0c369685e59cfea7-82FdsK
13438168,海贼玩跑跑,https://hbimg.huabanimg.com/1edae3ce6fe0f6e95b67b4f8b57c4cebf19c501b397e-BXwiW6
28593155,源稚生,https://hbimg.huabanimg.com/626cfd89ca4c10e6f875f3dfe1005331e4c0fd7fd429-9SeJeQ
28201821,合伙哼哼,https://hbimg.huabanimg.com/f59d4780531aa1892b80e0ec94d4ec78dcba08ff18c416-769X6a
28255146,漫步AAA,https://hbimg.huabanimg.com/3c034c520594e38353a039d7e7a5fd5e74fb53eb1086-KnpLaL
30537613,配䦹,https://hbimg.huabanimg.com/efd81d22c1b1a2de77a0e0d8e853282b83b6bbc590fd-y3d4GJ
22665880,日后必火,https://hbimg.huabanimg.com/69f0f959979a4fada9e9e55f565989544be88164d2b-INWbaF
16748980,keer521521,https://hbimg.huabanimg.com/654953460733026a7ef6e101404055627ad51784a95c-B6OFs4
30536510,“西辞”,https://hbimg.huabanimg.com/61cfffca6b2507bf51a507e8319d68a8b8c3a96968f-6IvMSk
30986577,艺成背锅王,https://hbimg.huabanimg.com/c381ecc43d6c69758a86a30ebf72976906ae6c53291f9-9zroHF
26409800,CsysADk7,https://hbimg.huabanimg.com/bf1d22092c2070d68ade012c588f2e410caaab1f58051-ahlgLm
30469116,18啊全阿,https://hbimg.huabanimg.com/654953460733026a7ef6e101404055627ad51784a95c-B6OFs4
15514336,W/小哥,https://hbimg.huabanimg.com/a30f5967fc0acf81421dd49650397de63c105b9ead1c-nVRrNl
17473505,椿の花,https://hbimg.huabanimg.com/0e38d810e5a24f91ebb251fd3aaaed8bb37655b14844c-pgNJBP
19165177,っ思忆゜♪,https://hbimg.huabanimg.com/4815ea0e4905d0f3bb82a654b481811dadbfe5ce2673-vMVr0B
16059616,格林熊丶,https://hbimg.huabanimg.com/8760a2b08d87e6ed4b7a9715b1a668176dbf84fec5b-jx14tZ
30734152,sCWVkJDG,https://hbimg.huabanimg.com/f31a5305d1b8717bbfb897723f267d316e58e7b7dc40-GD3e22
24019677,虚无本心,https://hbimg.huabanimg.com/6fdfa9834abe362e978b517275b06e7f0d5926aa650-N1xCXE
16670283,Y-雨后天空,https://hbimg.huabanimg.com/a3bbb0045b536fc27a6d2effa64a0d43f9f5193c177f-I2vHaI
21512483,汤姆2,https://hbimg.huabanimg.com/98cc50a61a7cc9b49a8af754ffb26bd15764a82f1133-AkiU7D
16441049,笑潇啸逍小鱼,https://hbimg.huabanimg.com/ae8a70cd85aff3a8587ff6578d5cf7620f3691df13e46-lmrIi9
24795603,⁢⁢⁢⁢⁢v,https://hbimg.huabanimg.com/a7183cc3a933aa129d7b3230bf1378fd8f5857846cc5-3tDtx3
29819152,妮玛士珍多,https://hbimg.huabanimg.com/ca4ecb573bf1ff0415c7a873d64470dedc465ea1213c6-RAkArS
19101282,陈勇敢❤,https://hbimg.huabanimg.com/ab6d04ebaff3176e3570139a65155856871241b58bc6-Qklj2E
28337572,爱意随风散,https://hbimg.huabanimg.com/117ad8b6eeda57a562ac6ab2861111a793ca3d1d5543-SjWlk2
17342758,幸运instant,https://hbimg.huabanimg.com/72b5f9042ec297ae57b83431123bc1c066cca90fa23-3MoJNj
18483372,Beau染,https://hbimg.huabanimg.com/077115cb622b1ff3907ec6932e1b575393d5aae720487-d1cdT9
22127102,栽花的小蜻蜓,https://hbimg.huabanimg.com/6c3cbf9f27e17898083186fc51985e43269018cc1e1df-QfOIBG
13802024,LoveHsu,https://hbimg.huabanimg.com/f720a15f8b49b86a7c1ee4951263a8dbecfe3e43d2d-GPEauV
22558931,白驹过隙丶梨花泪う,https://hbimg.huabanimg.com/e49e1341dfe5144da5c71bd15f1052ef07ba7a0e1296b-jfyfDJ
11762339,cojoy,https://hbimg.huabanimg.com/5b27f876d5d391e7c4889bc5e8ba214419eb72b56822-83gYmB
30711623,雪碧学长呀,https://hbimg.huabanimg.com/2c288a1535048b05537ba523b3fc9eacc1e81273212d1-nr8M4t
18906718,西霸王,https://hbimg.huabanimg.com/7b02ad5e01bd8c0a29817e362814666a7800831c154a6-AvBDaG
31037856,邵阳的小哥哥,https://hbimg.huabanimg.com/654953460733026a7ef6e101404055627ad51784a95c-B6OFs4
26830711,稳健谭,https://hbimg.huabanimg.com/51547ade3f0aef134e8d268cfd4ad61110925aefec8a-NKPEYX

代码实现示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import os
import requests

with open('files/movie.csv', mode='r', encoding='utf-8') as file_object:
file_object.readline()
for line in file_object:
user_id, username, url = line.strip().split(',')
print(username, url)
# 1.根据URL下载图片
res = requests.get(
url=url,
headers={
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
}
)
# 检查images目录是否存在?不存在,则创建images目录
if not os.path.exists("images"):
# 创建images目录
os.makedirs("images")

# 2.将图片的内容写入到文件
with open("images/{}.png".format(username), mode='wb') as img_object:
img_object.write(res.content)

练习:请用csv模块对上述示例进行修改。

二、ini格式文件

ini文件是Initialization File的缩写,平时用于存储软件的的配置文件。例如:MySQL数据库的配置文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-bin=py-mysql-bin
character-set-server=utf8
collation-server=utf8_general_ci
log-error=/var/log/mysqld.log
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid

[client]
default-character-set=utf8

这种格式是可以直接使用open来出来,考虑到自己处理比较麻烦,所以Python为我们提供了更为方便的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import configparser

config = configparser.ConfigParser()
config.read('files/my.ini', encoding='utf-8')
# config.read('files/my.ini', encoding='utf-8')

# 1.获取所有的节点
"""
result = config.sections()
print(result) # ['mysqld', 'mysqld_safe', 'client']
"""

# 2.获取节点下的键值
"""
result = config.items("mysqld_safe")
print(result) # [('log-error', '/var/log/mariadb/mariadb.log'), ('pid-file', '/var/run/mariadb/mariadb.pid')]

for key, value in config.items("mysqld_safe"):
print(key, value)
"""

# 3.获取某个节点下的键对应的值
"""
result = config.get("mysqld","collation-server")
print(result)
"""

# 4.其他

# 4.1 是否存在节点
# v1 = config.has_section("client")
# print(v1)

# 4.2 添加一个节点
# config.add_section("group")
# config.set('group','name','zhangyafei')
# config.set('client','name','zhangyafei')
# config.write(open('files/new.ini', mode='w', encoding='utf-8'))

# 4.3 删除
# config.remove_section('client')
# config.remove_option("mysqld", "datadir")
# config.write(open('files/new.ini', mode='w', encoding='utf-8'))
  • 读取所有节点

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import configparser

    config = configparser.ConfigParser()
    config.read('files/my.conf', encoding='utf-8')
    # config.read('my.conf', encoding='utf-8')
    ret = config.sections()
    print(ret)

    >>输出
    ['mysqld', 'mysqld_safe', 'client']
  • 读取节点下的键值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import configparser

    config = configparser.ConfigParser()
    config.read('files/my.conf', encoding='utf-8')
    # config.read('my.conf', encoding='utf-8')
    item_list = config.items("mysqld_safe")
    print(item_list)

    >>输出
    [('log-error', '/var/log/mariadb/mariadb.log'), ('pid-file', '/var/run/mariadb/mariadb.pid')]
  • 读取节点下值(根据 节点+键 )

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import configparser

    config = configparser.ConfigParser()
    config.read('files/my.conf', encoding='utf-8')

    value = config.get('mysqld', 'log-bin')
    print(value)

    >>输出
    py-mysql-bin
  • 检查、删除、添加节点

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import configparser

    config = configparser.ConfigParser()
    config.read('files/my.conf', encoding='utf-8')
    # config.read('my.conf', encoding='utf-8')
    # 检查
    has_sec = config.has_section('mysqld')
    print(has_sec)
    # 添加节点
    config.add_section("SEC_1")
    # 节点中设置键值
    config.set('SEC_1', 'k10', "123")
    config.set('SEC_1', 'name', "哈哈哈哈哈")
    config.add_section("SEC_2")
    config.set('SEC_2', 'k10', "123")
    # 内容写入新文件
    config.write(open('files/xxoo.conf', 'w'))
    # 删除节点
    config.remove_section("SEC_2")
    # 删除节点中的键值
    config.remove_option('SEC_1', 'k10')
    config.write(open('files/new.conf', 'w'))

三、Excel格式文件

Python内部未提供处理Excel文件的功能,想要在Python中操作Excel需要按照第三方的模块。

1
pip install openpyxl

此模块中集成了Python操作Excel的相关功能,接下来我们就需要去学习该模块提供的相关功能即可。

1. 读Excel

  • 读sheet

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    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)
    """
  • 读sheet中单元格的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    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)
    """
  • 读合并的单元格

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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
    1
    2
    3
    4
    5
    6
    from openpyxl import load_workbook

    wb = load_workbook('files/p1.xlsx')
    sheet = wb.worksheets[2]
    for row in sheet.rows:
    print(row)
    1
    2
    3
    4
    5
    6
    >>> 输出结果
    (<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文件基础上写内容。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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文件写内容。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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操作基本上都相同。

表格相关操作

  • 导入模块

    1
    from openpyxl import workbook
  • 初始化

    1
    wb = workbook.Workbook() # Sheet
  • 修改sheet名称

    1
    2
    3
    sheet = wb.worksheets[0]
    sheet.title = "数据集"
    wb.save("p2.xlsx")
  • 创建sheet并设置sheet颜色

    1
    2
    3
    sheet = wb.create_sheet("工作计划", 0)
    sheet.sheet_properties.tabColor = "1072BA"
    wb.save("p2.xlsx")
  • 默认打开的sheet

    1
    2
    wb.active = 0
    wb.save("p2.xlsx")
  • 拷贝sheet

    1
    2
    3
    4
    5
    6
    sheet = wb.create_sheet("工作计划")
    sheet.sheet_properties.tabColor = "1072BA"

    new_sheet = wb.copy_worksheet(wb["Sheet"])
    new_sheet.title = "新的计划"
    wb.save("p2.xlsx")
  • 删除sheet

    1
    2
    del wb["用户列表"]
    wb.save('files/p2.xlsx')

单元格相关操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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"] = "james"
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模块可以实现对压缩文件的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import shutil

# 1. 压缩文件
"""
# base_name,压缩后的压缩包文件
# format,压缩的格式,例如:"zip", "tar", "gztar", "bztar", or "xztar".
# root_dir,要压缩的文件夹路径
"""
# shutil.make_archive(base_name='datafile',format='zip',root_dir='files')


# 2. 解压文件
"""
# filename,要解压的压缩包文件
# extract_dir,解压的路径
# format,压缩文件格式
"""
# shutil.unpack_archive(filename='datafile.zip', extract_dir='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. 程序当前路径

项目中如果使用了相对路径,那么一定要注意当前所在的位置。

例如:在G:/学习/Python学习\Python基础/code路径下编写 demo.py文件

1
2
with open("a1.txt", mode='w', encoding='utf-8') as f:
f.write("你好呀")

用以下两种方式去运行:

  • 方式1,文件会创建在 G:/学习/Python学习/Python基础/code 目录下。

    1
    2
    cd G:/学习/Python学习/Python基础/code
    python demo.py
  • 方式2,文件会创建在 G:/学习目录下。

    1
    2
    cd G:/学习
    python `G:/学习/Python学习/Python基础/code/demo.py

实际开发使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import os

"""
# 1.获取当前运行的py脚本所在路径
abs = os.path.abspath(__file__)
print(abs) # G:\学习\Python学习\Python基础\code\chapter20\路径相关.py
path = os.path.dirname(abs)
print(path) # G:\学习\Python学习\Python基础\code\chapter20
# """
base_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(base_dir, 'files', 'info.txt')
print(file_path)
if os.path.exists(file_path):
file_object = open(file_path, mode='r', encoding='utf-8')
data = file_object.read()
file_object.close()

print(data)
else:
print('文件路径不存在')

3. 文件和路径相关

  • 导入相关模块

    1
    2
    import shutil
    import os
  • 获取当前脚本绝对路径

    1
    2
    abs_path = os.path.abspath(__file__)
    print(abs_path)
  • 获取当前文件的上级目录

    1
    2
    base_path = os.path.dirname( os.path.dirname(路径) )
    print(base_path)
  • 路径拼接

    1
    2
    3
    4
    5
    p1 = os.path.join(base_path, 'xx')
    print(p1)

    p2 = os.path.join(base_path, 'xx', 'oo', 'a1.png')
    print(p2)
  • 判断路径是否存在

    1
    2
    exists = os.path.exists(p1)
    print(exists)
  • 创建文件夹

    1
    os.makedirs(路径)
    1
    2
    3
    path = os.path.join(base_path, 'xx', 'oo', 'uuuu')
    if not os.path.exists(path):
    os.makedirs(path)
  • 判断是否是文件夹

    1
    2
    3
    4
    5
    6
    7
    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
  • 删除文件或文件夹

    1
    os.remove("文件路径")
    1
    2
    path = os.path.join(base_path, 'xx')
    shutil.rmtree(path)
  • 拷贝文件夹

    1
    shutil.copytree("D:/data/files","E:/data/files")
  • 拷贝文件

    1
    2
    shutil.copy("D:/data/xx.png","E:/data/")
    shutil.copy("D:/data/xx.png","E:/data/yy.png")
  • 文件或文件夹重命名

    1
    2
    shutil.move("D:/data/xx.png","D:/data/xx2.png")
    shutil.move("D:/data/files","D:/data/images")

六、简单的总结

上一节和本节我们主要围绕着常见文件相关操作来展开进行讲解,让大家能够基于Python处理不同格式的文件。由于涉及的知识点比较多,所以这两节的内容学起来会比较耗时,但都比较简单,只需要理解并编写好相关笔记以便后期开发时翻阅。最后再次强调一下文件处理时的注意问题:

  1. 文件相对路径,在使用相对路径时可能会执行程序的目录不同,导致路径出问题。所以,如若使用相对路径请务必清楚当前运行程序所在目录。

  2. 文件绝对路径(推荐),不要将文件路径写死,而是基于 os 模块中的相关功能自动化获取绝对路径,以方便项目移动到其他文件或电脑上。

    1
    2
    3
    import os
    base_dir = os.path.dirname(os.path.abspath(__file__))
    file_path = os.path.join(base_dir, 'files', 'info.txt')
  3. 路径转义

    • 手动写路径,需要自己在路径中添加 r 或 加入 \ 来进行处理。
    • 基于os.path.join拼接,内部自动处理,不需要手动处理。
  4. 内置函数、内置模块、第三方模块的区别?

  5. 如何去下载安装第三方模块?

    1
    pip install 模块名称
    • requests模块,可以用来发送网络请求。
    • openpyxl模块,处理Excel格式的文件。
  6. 基本文件的读写、打开模式、上下文管理。

  7. 其他格式:csv、ini、excel格式的处理(无序记忆,做好笔记即可)。

将来如果大家使用Python做数据分析,很有可能会用到名为pandas的三方库,它是Python数据分析的神器之一。它能够轻松处理csv、excel等各种常见格式的数据,完成各种复杂的操作,尤其对于大文件优势更加明显。后期我会出一个pandas系列的文章,到时候可以领略它的神奇。

赞赏一下吧~