常用文件读写&CSV文件读写&对象的序列化和反序列化

前言:

  • 意识:python中一切皆是对象!
  • 常见文件的读写分类:
    • 1.普通文本文件:txt py md html doc等
    • 2.二进制文件:图片,音频,视频,压缩包等
    • 3.csv文件:.csv,需要借助于系统模块csv
    • 4.对象的序列化和反序列化:pickle和json
    • 5.excel文件:需要借助于第三方模块

1、常用文件读写(除了文件夹其余都是文件)

  • 1.1、在代码中文件读写之前都需要先打开文件:open(file,mode,encoding)

    • file:需要打开的文件名称或文件的路径
    • 文件名称:需要打开的文件和当前py文件在同一个目录下,不常用
    • 文件路径:需要打开的文件和当前py文件不在同一个目录下,可以使用相对路径或绝对路径
    • mode:打开文件的模式
      • ‘r’ open for reading (default),普通文件的读取
      • ‘w’ open for writing, truncating the file first,普通文件的写入【删除原文件,生成一个新的文件】
      • ‘a’ open for writing, appending to the end of the file if it exists,普通文件的写入【追加】
      • ‘rb’ 打开二进制文件用于读取
      • ‘wb’ 打开二进制文件用于写入
      • encoding:文件的编码格式,常用的编码格式:utf-8/gbk
    • 注意:不管读还是写,打开文件一定记得关闭!!!!(避免占用系统内存资源)
  • 1.2、注意:

    • a.打开文件的时候,encoding的设置一定要和文件本身的编码格式保持一致,否则写入会出现乱码的情况,读取直接报错UnicodeDecodeError
    • b.如果要写入内容,mode可以使用w或a,w:覆盖,a:追加
    • c.读取或写入的时候,文件的路径建议使用相对路径
  • 1.3、读文件:

    • 读文件,则要读取的文件一定要存在。
    • 对于读文件来说,open函数返回值就是打开的文件对象
    • read():默认情况,全部读取,适合文件内容较少的情况。
    • readline():读取一行,读取一行后,如果继续调用readline,会继续读下一行
    • readlines():读取全部内容,返回一个列表,每行内容是列表中的一个元素
  • 1.4、写文件:

    • 写文件,文件可以不存在,在打开文件(open)过程中可以自动创建
    • 在给文件写入内容时,mode用w或a,参见上文(w:覆盖,a:追加)
    • write(要写入的内容)【注意一般“要写入的内容”是字符串】,file.write(str)的参数是一个字符串,就是你要写入文件的内容。
    • writelines(要写入的内容,可以用换行转义字符\n),file.writelines(sequence)的参数是可以是字符串,也可以是字符串序列,比如列表,它会迭代帮你写入文件。
    • 注意:由于写入的过程是从内存到磁盘完成的,所以在写入完成后要加上刷新函数:flush()
  • 1.5、循环读取

    • 1、通过read(size)
    • 2、通过readline()
  • 1.6、with上下文:

语法:
with open()  as  变量:
    读取/写入
- a. with上下文其实是简化了文件读写的三步曲
- b. 使用with的方式之后,读取和写入文件之后,无需手动关闭文件,当with代码块执行完毕,对应的文件会自动关闭
- c. 变量表示文件描述符,也就是文件对象
- d. 当通过with的方式打开文件,则文件读取和写入的操作一定要在with代码块中完成,
  否则文件会被关闭掉,无法操作【ValueError: I/O operation on closed file.】
  • 1.7、二进制文件读写
    • 1.‘rb’:打开二进制文件用于读取;‘wb’:打开二进制文件用于写入;
    • 2.打开二进制文件用于读写,无需设置encoding参数
#=======================================================================
"""
1、常用文件读写
"""
#1.1文件的读操作(t1.txt用于测试)
f = r'./dir22/t1.txt'   #这里r的目的是避免字符串当中出现转义字符
f1 = open(f,'r',encoding='utf-8')
r1 = f1.read()
print(r1)   #结果会读取t1.txt中的内容
f1.close()

print("-"*40)

f = r'./dir22/t1.txt'
f1 = open(f,'r',encoding='utf-8')
r2 = f1.readline()
print(r2)   #读第一行
r2 = f1.readline()
print(r2)   #读第二行(但是会和第一行之间有空格,因为第一行读完有个换行符,print自带一个换行符)
f1.close()

print("-"*40)

f = r'./dir22/t1.txt'
f1 = open(f,'r',encoding='utf-8')
r2 = f1.readlines()
print(r2)   #读第一行
f1.close()  #['1231414141\n', '421414141414\n', '555555555555\n', 'affdsffggafgadfg']

print("-"*40)

#1.2、文件的写操作
#用t2.txt测试w自动创建和a附加
print('用w打开文件,用write写入')
f = r'./dir22/t2.txt'
f1 = open(f,'w',encoding='utf-8')
f1.write('111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111')
f1.flush()  #当需要写入的内容比较多时,可以通过flush刷新,提高写入的效率
f1.close()

print("-"*40)

print('用a打开文件,用write写入')
f = r'./dir22/t2.txt'
f1 = open(f,'a',encoding='utf-8')
f1.write('\n3\n222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222')
f1.flush()  #当需要写入的内容比较多时,可以通过flush刷新,提高写入的效率
f1.close()

print("-"*40)

#用t3.txt测试a的自动创建功能以及a搭配writelines的使用
print('用w打开文件,用writelines写入')
f = r'./dir22/t3.txt'
f1 = open(f,'a',encoding='utf-8')
a = ['1231313','22222222222','4444444444']
f1.writelines(a)    #1231313222222222224444444444不换行,要加上\n才会换行
f1.close()

print("-"*40)

print('用a打开文件,用write写入')
f = r'./dir22/t3.txt'
f1 = open(f,'w',encoding='utf-8')
f1.writelines('\n22222222222222222222\n222222222222222222222\n22222222222222222222\n22222222222222222222222222222')
#会正常在\n位置换行
f1.close()

print("-"*40)

#1.3、循环读取
import os,math
#read(size):适用于文件内容量非常大的情况下,使用循环可以提高读取效率
f = r'./dir22/t4.txt'
T_size = os.path.getsize(f)
size = 1024 #2的次方

#方法1:测试read(size)   size表示要读取的字符数量
f1 = open(f,'r',encoding='utf-8')
print(f1.read(11))
f1.close()

f1 = open(f,'r',encoding='utf-8')
while T_size > 0:
    r = f1.read(size)
    print(r)
    T_size -= size
    #结果会正常打印所有内容
f1.close()

print("-"*40)

#方法2:
f1 = open(f,'r',encoding='utf-8')
s = 30
print(f'T_size:{T_size},T_size/s:{T_size/s}')
n = 0
while n < math.ceil(T_size/s):
    r = f1.read(s)
    print(r,'over')
    n += 1
    #打印会多打印很多行,猜想是因为T_size和s不是同一单位
f1.close()

print("-"*40)

#方法3:了解工作原理
f1 = open(f,'r',encoding='utf-8')
r = f1.readline()   #按行读取
while r:
    print(r)
    r = f1.readline()
f1.close()
#打印结果是全部打印,但是会有多出来的空行

print("-"*40)

#1.4、with上下文(用t4实现)
#写文件
f = r'./dir22/t4.txt'
with open(f,'w',encoding='utf-8') as f1:
    f1.write('''88888888888888888888
7777777777777777777777
6666666666666666666666''')
'''
t4中结果:
88888888888888888888
7777777777777777777777
6666666666666666666666
'''
#读文件
f = r'./dir22/t4.txt'
with open(f,'r',encoding='utf-8') as f1:
    r = f1.read()
    print(r)
'''
控制台打印结果:
88888888888888888888
7777777777777777777777
6666666666666666666666
'''

print("-"*40)

#1.5、二进制文件的读写(先将一个图片写入文件,然后将文件读出来,展示成图片)
f = r'.\dir22\image.png'
with open(f,'rb') as f1:
    r = f1.read()
    print(r)    #结果为\xxx组成的码值序列
with open(r'.\dir22\image2.png','wb') as f1:
    f1.write(r) #结果是image2.png生成和image.png一样的图片

2、CSV文件读写()

  • CSV(Comma Separated Values逗号分隔值)
  • .csv是一种文件格式(如.txt、.doc等),也可理解.csv文件就是一种特殊格式的纯文本文件。即是一组字符序列,字符之间用英文字符的逗号或制表符(Tab)分隔。所以,CSV文件本身就是是个纯文本文件,这种文件格式经常用来作为不同程序之间的数据交互的格式。
  • 在windows系统环境上.csv文件打开方式有多种,如记事本、excel、Notepad++等,只要是文本编辑器都能正确打开
  • csv文件需要引入对应模块
  • csv文件读取需要特定方法,且csv.reader(f)返回的是一个容器,里面内容以列表形式存放
"""
2、CSV文件读写
"""
import csv
f = open(r".\dir22\t5.csv",'r',encoding='gbk')
#csv文件读取
csv_reader = csv.reader(f)
data_list = []
for row in csv_reader:
    data_list.append(row)
print(data_list)    #可以正常打印所有t5当中的元素,但是会以列表形式打印
f.close()
#用with上下文也可以读CSV文件

# csv文件写入
with open(r".\dir22\t5.csv",'w',encoding='gbk') as f:
    csv_writer = csv.writer(f)  #这种写入格式参考官方手册
    data = [['username', 'age', 'hobby', 'address'], ['zhangsan', '10', 'dance', 'beijing'],
            ['lisi', '20', 'sing', 'shanghai'], ['wangwu', '13', 'dance', 'guangzou']]
    # a.单行写入t2.csv
    # for row in data:
    #     csv_writer.writerow(row)

    # b.多行写入t3.csv
    csv_writer.writerows(data)  #最终t5.csv中文件会被写入
#同理也可以通过普通open方法来写入

3、对象序列化和反序列化

  • Python中一切皆对象
  • 对象的序列化:将Python中的对象持久化到磁盘上
  • 对象的反序列化:将磁盘上一个文件中的内容转换为Python对象
  • 注意:
    • 1.对象的序列化【相当于写入】和反序列化【相当于读取】通过pickle模块和json模块完成
    • 2.Python中 一切 皆对象,可以使用pickle或json模块的类型:数字,字符串,列表,字典。元组,集合,类,函数,模块等
  • python中序列化和反序列化有两种方式一种是【pickle模块】另一种是【json模块】
  • json只能序列化字典和列表,pickle相对使用广泛
"""
3、对象序列化和反序列化
"""
#3.1、pickle模块:所有python对象的序列化或反序列化
import  pickle

list1 = [45,56,6,78]    # 列表对象
class Person():
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __str__(self):
        return f"姓名:{self.name},年龄:{self.age}"

per = Person("张三",10)   # Person对象

# 对象的序列化【将python对象写入文件】
"""
pickle.dump(obj,file)
    obj:需要序列化的对象
    file:需要序列化到的文件对象,注意:必须以二进制的方式打开文件,wb
"""
f = r'.\dir22\t6.txt'
f1 = open(f,'wb')
pickle.dump(list1,f1)	#【dump v.转储,转存】
f1.close()
'''
t6.txt当中结果:
��
       ]�(K-K8KKNe.
'''

# 对象的反序列化【将序列化文件读入python文件】
"""
pickle.load(file)
    file:需要反序列化到的文件对象,注意:必须以位二进制的方式打开文件,rb
"""
f2 = open(f,'rb')
r = pickle.load(f2)		#【load v.载入】
print(r,type(r))    #[45, 56, 6, 78] <class 'list'>
f2.close()

# 尝试字典的序列化和反序列化
import pickle
p = r'dict.txt'
shopcar_dict = {'a1':1,'a2':2}
#序列化
with open(p,'wb') as f:
    pickle.dump(shopcar_dict,f)
#反序列化
with open(p,'rb') as f:
    r = pickle.load(f)
    print(r,type(r))    #{'a1': 1, 'a2': 2} <class 'd

#3.2、json模块:字典或列表的序列化和反序列化
'''
JSON和Python中数据类型的对应关系

JSON            Python      表示

object           dict             {}

array            list               []

json.dump():将Python中的字典或列表对象序列化到指定的文件中

json.dumps():将Python中的字典或列表对象序列化为json字符串

json.load():将指定的文件中的json字符串反序列化为Python中的字典或列表对象

json.loads():将json字符串反序列化为Python中的字典或列表对象

'''
import  json

data_dict = {
    "name": "中国",
    "province": [{
        "name": "黑龙江",
        "cities": {
            "city": ["哈尔滨", "大庆"]
        }
    }, {
        "name": "广东",
        "cities": {
            "city": ["广州", "深圳", "珠海"]
        }
    }, {
        "name": "台湾",
        "cities": {
            "city": ["台北", "高雄"]
        }
    }, {
        "name": "新疆",
        "cities": {
            "city": ["乌鲁木齐"]
        }
    }]
}
print(data_dict)    #打印上面的字典
print(type(data_dict))  #<class 'dict'> 这说明josn中object原来格式是python中的字典dict

# 1.对象的序列化

"""
json.dump():将Python中的字典或列表对象序列化到指定的文件中
json.dumps():将Python中的字典或列表对象序列化为json字符串
"""
# a.json.dumps(obj) Serialize ``obj`` to a JSON formatted ``str`
# 注意:ensure_ascii默认值为True,表示最后的结果以编码格式显示,如果正常显示,则设置ensure_ascii=False
json_str = json.dumps(data_dict,ensure_ascii=False)
print(json_str) #打印结果就是字典里面的内容,但数据类型是str
print(type(json_str))   #<class 'str'>

# b.
f = r'.\dir22\t7.json'
with open(f,'w',encoding='utf-8') as f1:
    json.dump(data_dict,f1,ensure_ascii=False)  #t7.txt当中会把字典整个写入【序列化】

# 2.对象的反序列化
"""
json.load():将指定的文件中的json字符串反序列化为Python中的字典或列表对象
json.loads():将json字符串反序列化为Python中的字典或列表对象
"""
# a.这里对应dumps的结果
r = json.loads(json_str)
print(r)    #字典内容
print(type(r))  #<class 'dict'>

# b.这里对应dump的结果
with open(f,'r',encoding='utf-8') as f2:
    r1 = json.load(f2)
    print(r1)   #字典内容
    print(type(r1)) ##<class 'dict'>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值