python | 数据持久化 <file>&<excel>&<json>&<csv>模块基本操作

拿到数据后,通常需要对数据进行保存、加载等操作

这篇文章将介绍文件、excel、json数据、csv模块的基本操作,容易上手,解决一些简单的数据保存问题

1. 文件操作

计算机的文件,就是存储在某种长期储存设备上的一段数据

长期存储设备包括:硬盘、U 盘、移动硬盘、光盘…

文本文件和二进制文件

  • 文本文件
    • 可以使用文本编辑软件查看
    • 本质上还是二进制文件
    • 例如:python 的源程序
  • 二进制文件
    • 保存的内容不是给人直接阅读的,而是提供给其他软件使用的
    • 例如:图片文件、音频文件、视频文件等等

1.1 文件的基本操作

操作文件的函数/方法

Python 中要操作文件需要记住 1 个函数和 3 个方法

序号函数/方法说明
01open打开文件,并且返回文件操作对象
02read将文件内容读取到内存
03write将指定内容写入文件
04close关闭文件
  • open 函数负责打开文件,并且返回文件对象
  • read/write/close 三个方法都需要通过 文件对象 来调用

1.1.1 打开文件的方式

  • open 函数默认以只读方式打开文件,并且返回文件对象

语法如下:

f = open("文件名", "访问方式")
访问方式说明
r以只读方式打开文件。文件的指针将会放在文件的开头,这是默认模式。如果文件不存在,抛出异常
w以只写方式打开文件。如果文件存在会被覆盖。如果文件不存在,创建新文件
a以追加方式打开文件。如果该文件已存在,文件指针将会放在文件的结尾。如果文件不存在,创建新文件进行写入
r+以读写方式打开文件。文件的指针将会放在文件的开头。如果文件不存在,抛出异常
w+以读写方式打开文件。如果文件存在会被覆盖。如果文件不存在,创建新文件
a+以读写方式打开文件。如果该文件已存在,文件指针将会放在文件的结尾。如果文件不存在,创建新文件进行写入
  • 频繁的移动文件指针,会影响文件的读写效率,一般用只读、只写的方式操作文件

1.1.2 操作文件

open('hello.txt', 'r')

函数的第一个参数是要打开的文件名(文件名区分大小写)

  • read 方法可以一次性读入并返回文件的所有内容

    • readline 方法可以一次读取一行内容,读完一行后指针指向下一行开头,便于读取大文件
    • readlines 读出文件所有行,返回以每行内容为元素的列表
  • write 方法覆盖写入字符串或字节流

    • writelines 将一个元素为字符串的列表写入文件的首行,自动变成首尾相连的字符串
  • close方法负责关闭文件

    如果 忘记关闭文件,会造成系统资源消耗,而且会影响到后续对文件的访问

  • 注意:read 方法执行后,会把 文件指针 移动到 文件的末尾

li = ['hello', 'world', '!', ]

f = open('hello.txt', 'w')
f.writelines(li)
f.close()

f = open('hello.txt', 'r')
s = f.read()
print(s)
f.close()

1.2目录操作

  • 在 终端 / 文件浏览器、 中可以执行常规的 文件 / 目录 管理操作,例如:

    • 创建、重命名、删除、改变路径、查看目录内容、……
  • Python 中,如果希望通过程序实现上述功能,需要导入 os 模块

1.2.1 文件操作

序号方法名说明示例
01rename重命名文件os.rename(源文件名, 目标文件名)
02remove删除文件os.remove(文件名)

1.2.2 目录操作

序号方法名说明示例
01listdir目录列表os.listdir(目录名)
02mkdir创建目录os.mkdir(目录名)
03rmdir删除目录os.rmdir(目录名)
04getcwd获取当前目录os.getcwd()
05chdir修改工作目录os.chdir(目标目录)
06path.isdir判断是否是文件os.path.isdir(文件路径)

提示:文件或者目录操作都支持 相对路径 和 绝对路径

值得注意的是,os.mkdir( )只能创建父目录存在的目标目录,而os.makedirs( )可以完全按照路径要求递归创建目录;
os.path.isdir( )用于判断是否有目录存在,而os.path.exists( )判断是否有指定文件存在,关注文件类型
示例:

os.rename('hello.txt', 'helloworld!.txt')
os.remove('helloworld!.txt')

print(os.listdir(r'F:\PycharmProjects\demo316'))#获取指定目录下的所有子目录、文件名
os.mkdir(r'F:\PycharmProjects\666')#在指定路径下创建目录
os.rmdir(r'F:\PycharmProjects\666')
print(os.getcwd())
os.chdir(r'F:\PycharmProjects\666')#将工作目录从当前目录跳转到指定目录
os.path.isdir(r'F:\PycharmProjects\777'):

2. excel

openpyxl是一个Python库,用于读取/写入Excel 2010 xlsx / xlsm / xltx / xltm文件。

它的诞生是因为缺少可从Python本地读取/写入Office Open XML格式的库。

Excel 文件三个对象

workbook: 工作簿,一个excel文件包含多个sheet。
sheet:工作表,一个workbook有多个,表名识别,如“sheet1”,“sheet2”等。
cell: 单元格,存储数据对象

1、openpyxl 读写单元格时,单元格的坐标位置起始值是(1,1),即下标最小值为1,否则报错!

2、openpyxl 支持直接横纵坐标访问,如 A1,B2…

2.1 创建、写入并保存工作簿

只需导入Workbook 对象就可以创建工作簿

表创建时会自动命名,按顺序编号(Sheet,Sheet1,Sheet2等),可以通过Worksheet.title属性更改此名称。

# -*- coding: utf-8 -*-
from openpyxl import Workbook
# 创建工作簿
wb = Workbook()
# 创建一张表
sheet = wb.active
sheet.title = '表1'
# 创建新表
sheet2 = wb.create_sheet('表2')

在已创建的表中写入内容,通常有三种方式:

# 写入
sheet1['A1'] = 'A1' # 指定表中的位置,实现赋值
sheet1.cell(row=2, column=1, value='A2') # 对单元格进行操作
sheet1.cell(row=3, column=1).value = 'A3' # 同上,写法稍有不同

逐行写

行内容可以直接被列表覆盖
sheet.append(iterable)
添加一行到当前sheet的最底部(即逐行追加从第一行开始)
iterable必须是list,tuple,dict,range,generator类型的。
1,如果是list,将list从头到尾顺序添加。
2,如果是dict,按照相应的键添加相应的键值。
sheet1.append(['This is A1', 'This is B1', 'This is C1'])
sheet1.append({'A': 'This is A1', 'C': 'This is C1'})
sheet1.append({1: 'This is A1', 3: 'This is C1'})

最后是保存:

# 保存文件 excel 2010
wb.save('demo.xlsx')

2.2 读表操作

from openpyxl import load_workbook

# 加载工作簿
wb = load_workbook('demo.xlsx')

# 通过表明获取指定工作表
table = wb['表2']

# 获取行数和列数
rows = table.max_row
cols = table.max_column

# 循环遍历所有单元格的值
for row in range(rows):
    for col in range(cols):
        print(table.cell(row=row + 1, column=col + 1).value)

# 获取所有表名
sheet_names = wb.sheetnames
print(sheet_names[0])
ws = wb[(wb.sheetnames[0])]  # index为0为第一张表
# 活动表表名
print(wb.active.title)

逐行读取

# 返回一个生成器, 注意取值时要用value,例如:
for row in table['A1:I9']:
    for cell in row:
        print(cell.value)

3. json

目的: 将 Python 对象编码为 JSON 字符串,并将 JSON 字符串解码为 Python 对象。

json 模块提供了 API,将内存中的 Python 对象转换为 JSON 序列。JSON 具有以多种语言(尤其是 JavaScript)实现的优点。它在 REST API 中 Web 服务端和客户端之间的通信被广泛应用,同时对于应用程序间通信需求也很有用。 下面演示如何将一个Python数据结构转换为JSON:

3.1 编码和解码

Python 的默认原生类型(strintfloatlisttupledict)。

import json

data = {
    'name': 'ACME',
    'shares': 100,
    'price': 542.23
}

json_str = json.dumps(data)
print(json_str)
print(type(json_str))

运行结果:

{"name": "ACME", "shares": 100, "price": 542.23}
<class 'str'>

从无序的字典到有序的字符串,这个过程被称之为序列化。

最终我们将json保存到文件

with open('data.json', mode='w', encoding='utf-8') as f:
    f.write(json_str)

如果使用包含中文的json数据,保存到文件中会将中文转为unicode码

data = {
    'name': '小明',
}
{"name": "\u5c0f\u660e"}

解决办法: json_str = json.dumps(data, ensure_ascii=False)

3.2 读取数据

将json数据变为字典类型的这个过程被称之为反序列化

with open('data.json', mode='r', encoding='utf-8') as fp:
    data = json.load(fp)

print(data)
print(type(data))
print(data['price'])
{'name': 'ACME', 'shares': 100, 'price': 542.23}
<class 'dict'>
542.23

说到这里,可能会有疑问,为什么不直接用str( )将json数据强制变为字符串,再写入文件中保存,因为强制转为字符串后,读取的只能是字符串,用json.dumps( )转为字符串可以理解为给字符串加了一个标记,只有标记存在,才能用json.load( )去读取出字典类型的数据。

3.3 格式化输出

JSON 的结果是更易于阅读的。dumps() 函数接受几个参数以使输出更易读结果。

import json

data = {'a': 'A''b': (24)'c': 3.0}
print('DATA:'repr(data))	# DATA: {'a': 'A', 'b': (2, 4), 'c': 3.0}

unsorted = json.dumps(data)
print('JSON:', json.dumps(data))	# JSON: {"a": "A", "b": [2, 4], "c": 3.0}

编码,然后重新解码可能不会给出完全相同类型的对象。

特别是,元组成为了列表。

JSON跟Python中的字典其实是一样的,事实上JSON的数据类型和Python的数据类型是很容易找到对应关系的,如下面两张表所示。

PythonJSON
dictobject
list, tuplearray
strstring
int, float, int- & float-derived Enumsnumber
True / Falsetrue / false
Nonenull

需要注意的是,json除了可以是字典类型,也可以是元素为字典的列表。

4. CSV模块简介

csv文件格式是一种通用的电子表格和数据库导入导出格式。

python中有一个读写csv文件的包,直接import csv即可。

利用这个python包可以很方便对csv文件进行操作,一些简单的用法如下。

4.1 写入文件

我们把需要写入的数据放到列表中,写文件时会把列表中的元素写入到csv文件中。

import csv

lis = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
]

#  newline='' 就不会自动换行
with open('demo.csv', mode='w', encoding='utf-8', newline='') as f:
    # 实例化一个csv对象 写入数据
    csv_writer = csv.writer(f, delimiter='*')
    for li in lis:
        csv_writer.writerow(li)

delimiter='*'指定csv格式数据间的分隔符

保存在csv文件下的数据如下所示:

1*2*3*4
5*6*7*8

4.2 读取文件

with open('demo.csv', mode='r', encoding='utf-8') as f:
    csv_reader = csv.reader(f)
    for row in csv_reader:
        print(row)
['1*2*3*4']
['5*6*7*8']

有点需要注意的是,当用writer写数据时, None 会被写成空字符串,浮点类型会被调用 repr() 方法转化成字符串。所以非字符串类型的数据会被 str() 成字符串存储。所以当涉及到 unicode 字符串时,可以自己手动编码后存储或者使用csv提供的 UnicodeWriter

4.3 写入与读取字典

csv 还提供了一种类似于字典方式的读写,方式如下:

class csv.DictReader(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel'*args, **kwds)

class csv.DictWriter(csvfile, fieldnames, restval='', extrasaction='raise', dialect='excel'*args, **kwds)

其中 fieldnames 指定字典的 key 值,如果 reader 里没有指定那么默认第一行的元素,在 writer 里一定要指定这个。

import csv

with open('names.csv', 'w') as csvfile:
    fieldnames = ['first_name', 'last_name']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    writer.writeheader()
    writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})
    writer.writerow({'first_name': 'Lovely'})
    writer.writerow({'first_name': 'Wonderful', 'last_name': 'Spam'})

import csv

with open('names.csv', newline='') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        print(row['first_name'], row['last_name'])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值