Python数据永久化:文件内容操作

引言

文件是长久保存信息并允许重复和反复修改的重要方式,同时也是信息交换的重要途径。

  • 文本文件

扩展名为txt,log,ini的文件都属于文本文件,可以使用字处理软件如gredit、记事本、UltraEdit等进行编辑。

  • 二进制文件

常见的如图形图像文件、音视频文件、可执行文件、资源文件、各种数据库文件、各类Office文件等都属于二进制文件。二进制文件把信息以字节串(bytes)进行存储,无法使用记事本或其他普通字处理软件直接进行编辑,通常也无法直接阅读和理解,需要使用正确的软件进行解码或反序列化之后才能正确的读取、显示、修改或执行。

文件操作基本知识

  首先打开文件并创建文件对象,然后通过该文件对象对文件内容进行读取、写入、删除、修改等操作,最后关闭并保存文件内容。

内置函数open():open(file,mode='r',buffering = -1,encoding = None,errors = None,newlines = None,closefd = True,opener = None)

注意:如果执行正常,open()函数返回一个人可迭代的文件对象,通过该文件对象可以对文件进行读写操作,如果指定文件不存在、访问权限不够、磁盘空间不够或其他原因导致创建文件对象失败则抛出异常,f1 = open('file1.txt','r'),f2 = open('file2.txt','2').

当对文件内容操作完以后,一定亚欧鞍鼻文件对象,这样才能保证多做的任何修改都被保存到文件当中。

f1.close()

上下文管理语句with: 在实际开发中,读写文件应优先考虑使用上下文管理语句with,关键字with可以自动管理资源,不论因为什么原因跳出with块,总能保证文件被正常关闭。

with open(filename,mode,encoding) as fp:

#这里通过文件对象fp读写文件内容的语句

另外,上下文管理语句with还支持下面的用法,进一步简化了代码的编写。

with open('text.txt','r') as src,open('text_new.txt','w') as dst:

dst.write(src.read())  #类似于复制

  • 使用pickle模块读写二进制文件

  标准化pickle提供的dump()方法(protocol参数为True时可以实现压缩的效果)将数据进行序列化并写入文件,load()方法读取二进制文件内容并进行反序列化,还原为原来的信息。

import pickle

i = 13000000
a = 99.056
s = '中国人民 123abc'
lst = [[1,2,3],[4,5,6],[7,8,9]]
tu = (-5,10,8)
coll = {4,5,6}
dic = {'a':'apple','b':'banana','g':'grape','o':'orange'}
data = (i,a,s,lst,tu,coll,dic)

with open('sample_pickle.dat','wb') as f:
    try:
        pickle.dump(len(data),f) #要序列化的对象个数
        for item in data:
            pickle.dump(item,f) #序列化数据并写入文件
    except:
        print('写文件异常')

with open('sample_pickle.dat','rb') as f:
    n = pickle.load(f) #读出文件中的数据个数
    for i in range(n):
        x = pickle.load(f)
        print(x)
        
  • 使用struct模块读写二进制文件

使用struct模块时需要使用pack()方法把对象按指定的格式进行序列化,然后使用文件对象的write()方法将序列化的结果写入二进制文件;读取时需要使用文件对象的read()方法读取二进制文件的内容,然后使用struct模块unpack()方法反序列化得到原来的信息。


import struct

n = 1300000000
x = 996.45
b = True
s = 'a1@中国'
sn = struct.pack('if?',n,x,b) #序列化,i表示整数,f表示实数,“?”表示逻辑值

with open('sample_struct.dat','wb') as f:
    f.write(sn)
    f.write(s.encode()) #字符串需要编码为字节串在写入文件
    
with open('sample_struct.dat','rb') as f:
    sn = f.read(9)
    tu = struct.unpack('if?',sn) #使用指定格式反序列化
    n,x,b1 = tu #序列解包
    print('n = ',n,'x = ',x,'b1 = ',b1)
    s = f.read(9)
    s = s.decode() #字符串解码
    print('s = ',s)
  • 使用shelve模块操作二进制文件

Python标准库shelve也提供了二进制文件文件操作的功能,可以向字典赋值一样来写入人进制文件,也可以像字典一样读取二进制文件。

  • 其他常见类型二进制操作文件
Excel操作
from xlwt import *
import xlrd

book = Workbook() #创建新的excel文件
sheet1 = book.add_sheet("First") #添加新的worksheet
a1 = Alignment()
a1.horz = Alignment.HORZ_CENTER #对齐方式
a1.vert = Alignment.VERT_CENTER
borders = Borders()
borders.bottom = Borders.THICK #边框样式
style = XFStyle()
style.alignment = a1
Style.borders = borders
row = sheet1.row(0) #获取第0行
row.write(0,'test',style = style) #写入单元格
row = sheet1.row(1)
for i in range(5):
    row.write(i,i,style = style)#写入数字
row.write(5,'=SUM(A2:E2)',style = style)#写入公式
book.save(r'D:\test.xls') #保存文件

book = xlrd.open_workbook(r'D:\test.xls')
sheet1 = book.sheet_by_name('First')
row = sheet1.row(0)
print(row[0].value)
print(sheet1.row(1)[2].value)   
excel操作2
import openpyxl
from openpyxl import Workbook

fn = r'D:\test.xlsx' #文件名
wb = Workbook()  #创建工作簿
ws = wb.create_sheet(title = '你好,世界') #创建工作表
ws['A1'] = '这是第一个单元格' #单元格赋值
ws['B1'] = 3.1415926
wb.save(fn) #保存Excel文件

wb = openpyxl.load_workbook(fn) #打开已有的excel文件
ws = wb.worksheets[1] #打开指定索引的工作表
print(ws['A1'].value) #读取并输出指定单元格的值
ws.append([1,2,3,4,5]) #添加一行数据
ws.merge_cells('F2:F3') #合并单元格
ws['F2'] = "=sum(A2:E2)" #写入公式
for r in range(10,15):
    for c in range(3,8):
        _ = ws.cell(row = r,column = c,value = r*c) #写入单元格数据
wb.save(fn)

## 表格随机数据的生成

# -*- coding: utf-8 -*-
"""
Created on Thu Sep 23 22:11:58 2021

@author: 86176
"""

import openpyxl
from openpyxl import Workbook
import random

#生成随机数据
def generateRandomInformation(filename):
    workbook = Workbook()
    worksheet = workbook.worksheets[0]
    worksheet.append(['姓名','课程','成绩'])
    
    #中文名字中的第一、第二、第三个字
    first = '赵钱孙李'
    middle = '伟昀琛东'
    last = '坤艳志'
    subjects = ('语文','数学','英语')
    for i in range(200):
        line = []
        r = random.randint(1,100)
        name = random.choice(first)
        # 按一定概率生成只有两个字的中文名字
        if r > 50:
            name = name + random.choice(middle)
        name = name + random.choice(last)
        # 依次生成姓名、课程名称和成绩
        line.append(name)
        line.append(random.choice(subjects))
        line.append(random.randint(0,100))
        
        worksheet.append(line)
    
    # 保存数据,生成Excel2007格式的文件
    workbook.save(filename)
    
    
def getResult(oldfile,newfile):
    # 用于存放结果数据的字典
    result = dict()
    
    #打开原始数据
    workbook = openpyxl.load_workbook(oldfile)
    worksheet = workbook.worksheets[0]
    
    # 遍历原始数据
    for row in worksheet.rows:
        if row[0].value == '姓名':
            continue
        # 姓名、课程名称、本次成绩
        name,subject,grade = row[0].value,row[1].value,row[2].value
        
        # 获取当前姓名对应的课程名称和成绩信息
        # 如果result 字典中不包含,则返回空字典
        t = result.get(name,{})
        # 获取当前学生当前课程的成绩,若不存在,返回0
        f = t.get(subject,0)
        # 只保留该学生该课程的最高成绩
        if grade > f:
            t[subject] = grade
            result[name] = t
            
    workbook1 = Workbook()
    worksheet1 = workbook.worksheets[0]
    worksheet1.append(['姓名','课程','成绩'])

    # 将result字典中的结果数据写入Excel文件
    for name,t in result.items():
        print(name,t)
        for subject,grade in t.items():
            worksheet1.append([name,subject,grade])
    
    workbook1.save(newfile)
        
if __name__ == '__main__':
    oldfile = r'D:\test1.xlsx'
    newfile = r'D:\result.xlsx'
    generateRandomInformation(oldfile)
    getResult(oldfile,newfile)

# txt文件转xlsx文件

from openpyxl import Workbook

def main(txtFileName):
    new_XlsxFileName = txtFileName[:-3] + 'xlsx'
    wb = Workbook()
    ws = wb.worksheets[0]
    with open(txtFileName) as fp:
        for line in fp:
            line = line.strip().split(',')
            ws.append(line)
    wb.save(new_XlsxFileName)

main('test.txt')

# 使用Python标准库tarfile把当前文件夹中所有.py文件压缩为gzip格式的压缩文件,然后在解压缩到指定文件夹中。

# -*- coding: utf-8 -*-
"""
Created on Sat Sep 25 21:17:41 2021

@author: 86176
"""

import os
import tarfile

with tarfile.open('sample.tar','w:gz') as tar:
    for name in [f for f in os.listdir('.') if f.endswith('.py')]:
        tar.add(name)

with tarfile.open('sample.tar','r:gz') as tar:
    tar.extractall(path = 'sample')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值