Python复习 Day8 文件操作

一、文件

1.1 打开

1.1.1 open()

file = open(文件名, [打开模式], [读写文件的缓冲模式], [编码方式])

文件名:如果要打开的文件和当前文件在同一目录下,可直接用文件名,否则需要指定完整路径;

打开模式:可选参数,可以选择只读,只写,读写模式,默认为只读(r),需要用引号括起来;

缓冲模式:可选参数,表示读写文件的缓冲模式,0表示不缓存,1表示缓存,大于1表示缓冲区的大小,默认缓存;

编码方式:可选参数,编码方式默认是GBK,如果需要打开UTF-8编码的文件,需要写明,指定编码方式encoding='utf-8'。

1.1.2 打开模式

类别普通格式以二进制格式打开区分能否创建新文件
只读rrb

只能读,不能写。

指针在文件开头

覆盖wwb

可以写。区别:

w是覆盖原内容;a是保留原内容,在末尾追加

追加aab
读写覆盖w+wb+

可以读写。区别:

w+是覆盖原有内容;a+是保留原内容,在末尾追加;r+是在指针处写入内容,会覆盖指针后的内容,如果指针在开头,会覆盖整个文件内容

追加a+ab+
写入r+rb+

总结一下:

只读用r,创建文件用w, a;

覆盖原内容用w,不覆盖用a;

只读只写不带+,读写末尾带+;

以二进制形式打开时末尾带b,二进制常用于打开非文本文件,如图片、音频、视频等

1.1.3 创建

w, a, w+, a+都可以创造文件。

举个例子:

print('打开一个文件,如果不存在时就创建它')
f1 = open('123.tet', 'a+', encoding='utf-8')
# 创建并打开123.txt,并拥有读取和写入权限
f2 = open('123.png', 'rb')
# 以二进制形式打开非文本文件

1.1.4 关闭

之前我们打开文件是,file = open(filename, mode),这个模式打开的文件不能自动关闭,需要手动关闭文件。

关闭文件的语句:file.close()

file = open('123.txt','w+') # 打开文件
"""中间进行操作"""
file.close() # 关闭文件

1.1.5 with语句

如果我们担心忘记关闭文件,或者打开文件时抛出异常无法关闭,可以使用with语句。

with用途:

with语句可以保证无论文件是否抛出异常,都能在with语句执行完后关闭打开的文件。

with用法:

with open(filename, mode) as file:

        with语句

with语句可以指定打开文件后的一些操作,如果不想执行任何操作,可以用pass代替。例如:

with open('123.txt', 'w') as f3: # 指定变量f3,将打开文件的结果保存进变量f3
    pass

以上,打开文件的相关操作就告一段落了。

1.2 写入

1.2.1 写入一条

file.write(string)

string为要写入的字符串

1.2.2 写入多条

file.writelines(list)

list为要写入的字符串列表,每个列表元素都是要写入的字符串;

with open('123.txt', 'w+') as f3:    
    f3.write('春眠不觉晓,\n') # 单句写入需要添加换行符才会换行
    f3.write('处处闻啼鸟。\n') 
    f3.writelines(['夜来风雨声,', '花落知多少。']) # 一次写入多行

with open('123.txt', 'r') as f3:
    r = f3.readlines()
    print(r) # 读取文件的全部行
# ['春眠不觉晓,\n', '处处闻啼鸟。\n', '夜来风雨声,花落知多少。']

1.3 读取

1.3.1 读取字符和移动指针

1、读取字符

file.read(size)

① size为要读取的字符长度,不指定的话会读取全部文件;

② 从指针位置读取指定个数字符,如果不移动指针,默认从头读取

③ 只适用于用'r'和'r+'打开,否则会抛出异常

④ read()函数中,汉字、字母、数字均占一个字符,不同于seek()函数指标移动的字符计算

2、移动指针

file.seek(offset,[whence])

① offset为要移动的字符数,按汉字占2字符,英文字母和数字占1字符计算

② whence为指标开始移动的位置,0是从头开始计算,1是从当前位置,2是从文件尾开始计算,默认为0

with open('123.txt', 'w+') as f3:    # 指定变量f3,将打开文件的结果保存进变量f3
    f3.write('春眠不觉晓,')
    f3.write('处处闻啼鸟。')
    f3.writelines(['夜来风雨声,', '花落知多少。'])
with open('123.txt', 'r') as f3:
    r = f3.read(5)
    print(r) # 春眠不觉晓
    f3.seek(12) # 移动指针,从头移动,移动12个字符,汉字占2个,汉字标点占2个
    r = f3.read(5) # 在新的指针位置读取5个字符
    print(r) # 处处闻啼鸟

1.3.2 读取一行

file.readline()

① 有时,我们避免要读取的文件过大,会使用逐行读取的方法,这时我们可以使用readline()函数每次读取一行。readline(),从指针后读取一行。

② 同样,只适用于用'r'和'r+'打开。

1.3.3 读取全部行

file.readlines()

① 从指针后读取全部行,输出结果为一个字符串列表,每行是列表的一个元素。

② 遍历后能获得全部字符串文本。

与file.read()的区别:

file.read()输出结果为文本,file.readlines()输出结果为字符串列表。

# 读取一行
with open('123.txt', 'r') as f3:
    r = f3.readline() 
    print(r) # 春眠不觉晓,
# 读取全部(指针后的全部)
    r = f3.readlines() 
    print(r) # ['处处闻啼鸟。\n', '夜来风雨声,\n', '花落知多少。']
# 用read读取全部
with open('123.txt', 'r') as f3:
    r = f3.read()
    print(r) # 春眠不觉晓,
             # 处处闻啼鸟。
             # 夜来风雨声,
             # 花落知多少。

1.3.4 for-in循环

for in 循环可逐行输出以'r''r+'模式打开的只读文件,效果等同于使用file.readline()多次读取文件。

with open('123.txt', 'r') as f:
    # print(f)
    for line in f:
        print(line, end='')
        time.sleep(0.5)

""" 逐行输出
春眠不觉晓,
处处闻啼鸟。
夜来风雨声,
花落知多少。
"""

二、JSON

2.1 JSON是什么

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,以纯文本格式存储和表示数据,完全独立于语言。

因为其易于阅读和编写,使其成为一种流行的数据交换格式。常用于(摘自百度AI知道):

  1. 数据交换:JSON文件经常用于在不同的系统、应用程序或服务之间交换数据。由于其易于阅读和编写的特性,它成为了一种流行的数据交换格式。

  2. 数据存储:JSON文件也可以作为轻量级的数据存储方式。它们可以存储各种类型的数据,包括字符串、数字、对象(键值对集合)、数组等。这使得JSON文件成为缓存数据或存储配置信息的理想选择。

  3. 配置文件:许多应用程序使用JSON文件作为配置文件,因为它们提供了灵活且易于解析的结构来存储设置和参数。

  4. API响应:在Web开发中,许多RESTful API使用JSON作为响应格式。当客户端请求数据时,服务器通常会返回一个JSON格式的响应,其中包含所需的数据。

  5. 跨平台兼容性:由于JSON是基于文本的,它可以在任何支持文本处理的环境中使用,无论操作系统或编程语言如何。这使得JSON成为一种跨平台的、可移植的数据表示形式。

  6. 人类可读性:与二进制数据格式相比,JSON文件具有更好的可读性。它们使用标准的文本格式,因此可以轻松地用文本编辑器打开和编辑。

2.2 序列化

序列化是将数据结构或者对象状态转化为可储存,可传输的形式(如JSON),在这期间,对象将其当前状态写入到临时或持久性存储区。后续可以通过从存储区中读取数据或反序列化,重新创建该对象。

序列化常用于数据的存储和传输。如将对象保存到硬盘,或者通过网络发送对象。

2.2.1 dump和dumps

dump(Python对象名,存储json文件的变量):将Python对象按JSON格式序列化到文件中

dumps(Python对象名):将Python对象按JSON格式序列化为字符串

区别:因为dumps是返回序列化后的字符串,而dump是将序列化后的数据写入文件,所以,当需要将对象转换为字符串进行操作时,常用dumps序列化对象(如传输时);当需要存储对象时,常用dump序列化对象。

应用:

创建和写入文件

# JSON文件
import json


def main():
    # 储存了张三的字典
    dict1 = {
        'name': '张三',
        'age': 18,
        'hobby': 'reading',
        'school': 'QH',
        'major': ['Finance', 'Mathematics']
    }
    # 创建一个普通文件,保存数据
    try:
        with open('ordinary.txt', 'w+', encoding='utf-8') as txt:
            txt.write(str(dict1))
    except FileNotFoundError:
        print('无法打开指定的文件')
    except IOError:
        print('读写文件时发生错误')
    else:
        print('成功将%s的信息写入了txt文件' % dict1['name']) # 成功将张三的信息写入了txt文件
    finally:
        print('执行了一次写入txt文件的操作,文件名:ordinary.txt\n') # 执行了一次写入txt文件的操作,文件名:ordinary.txt

    # 创建一个JSON文件,保存数据
    try:
        with open('json.json', 'w+', encoding='utf-=8') as js:
            json.dump(dict1, js)
    except FileNotFoundError:
        print('无法打开指定的文件')
    except IOError:
        print('读写文件时发生错误')
    except LookupError:
        print('指定了未知的编码')
    except UnicodeDecodeError:
        print('读取文件时解码错误')
    else:
        print('成功将%s的信息写入了json文件' % dict1['name']) # 成功将张三的信息写入了json文件
    finally:
        print('执行了一次写入json文件的操作,文件名:json.json\n') # 执行了一次写入json文件的操作,文件名:json.json

    # 将张三信息转化为JSON字符串,方便传输
    json_data = json.dumps(dict1)
    print(json_data) # {"name": "\u5f20\u4e09", "age": 18, "hobby": "reading", "school": "QH", "major": ["Finance", "Mathematics"]}


if __name__ == '__main__':
    main()

在JSON文件中追加信息 :

import json


def main():
    """额外写入李四信息"""
    # 李四信息
    dict2 = {
        'name': '李四',
        'age': '18',
        'hobby': 'hiking',
        'school': 'BD',
        'major': ['Politics', 'History']
    }
    try:
        with open('json.json', 'a+', encoding='utf-8') as js:
            json.dump(dict2, js)
    except FileNotFoundError:
        print('打开文件时遇到问题')
    except IOError:
        print('读写文件时遇到问题')
    else:
        print('成功将%s的信息写入了json文件:json.json' % dict2['name']) # 成功将李四的信息写入了json文件:json.json
    finally:
        print('执行了一次追加json文件的操作,文件名:json.json') # 执行了一次追加json文件的操作,文件名:json.json

if __name__ == '__main__':
    main()

2.2.2 可以序列化JSON格式的Python对象

类型PythonJSON
字典dictobject
列表listarray(数组)
元组tuplearray
整数/浮点数int/floatnumber
布尔值True/Falsetrue/false
NoneNonenull
  1. 字典是Python中最常用的数据类型之一,也是JSON格式的主要表示形式。
  2. 元组本身不能被直接序列化为JSON,但可以将其先转换为列表,再序列化。
  3. 数组(array)是JSON格式中的一个特定类型,是由一系列的值(字符串、数字、对象、数组等)组成的集合,这些值由逗号分隔,并用方括号包围。类似Python中的列表(list)。
  4. 在JSON格式中,所有的字符串必须使用双引号(")。单引号(')或未引用的字符串在JSON中都是无效的。这是JSON规范的一个明确要求。

2.3 反序列化

反序列化则是从序列化表示形式(如JSON)中提取对象的过程。在反序列化期间,根据序列化的数据重新构造对象。

2.3.1 load和loads

load:将存储JSON数据的文件反序列化为Python对象

loads:将JSON字符串反序列化为Python对象

应用:

import json


dict1 = {
    'name': '张三',
    'age': 18,
    'hobby': 'reading',
    'school': 'QH',
    'major': ['Finance', 'Mathematics']
}

# 转化为JSON文件并保存
with open('json.json', 'w+', encoding='utf-8') as js:
    json.dump(dict1, js)
# 重新以阅读模式打开并读取 
with open('json.json', 'r', encoding='utf-8') as js:
    read = js.read()
    print('序列化为JSON格式的字典:', read)
# 反序列化JSON文件    
with open('json.json', 'r', encoding='utf-8') as js:
    info = json.load(js)  # 反序列化
    print('文件的反序列化:', info)
# 序列化为字符串    
data = json.dumps(info)
print('数据序列化为JSON字符串', data)
# JSON字符串反序列化
info2 = json.loads(data)
print('字符串的反序列化:', info2)

三、练习

3.1 将1-9999之间的质数分别写入三个文件中

"""
将1-9999之间的质数分别写入三个文件中
质数,只能被1和它本身整除的数,1不是质数
"""


def is_prime(i):
    """判断i是否是素数"""
    prime = True
    if i == 1:
        prime = False
    if i > 1:
        for j in range(2, int(i ** 0.5) + 1):
            if i % j == 0:
                prime = False
                break
    return prime


def prime_numbers(a, b):
    """寻找a,b之间的素数,不含b"""
    list1 = []
    for i in range(a, b):
        if is_prime(i):
            list1.append(i)
    return list1


def num_str(array, sep):
    """
    提供一个将保存int/float数据的列表/元组中元素转化为str的函数,
    并指定元素遍历后的分隔符,输出结果统一为列表。
    """
    new_list = []
    for i in array:
        if isinstance(i, (int, float)): # 使用isinstance检查类型,同样可以用于检查对象是否属于某个类
            item = str(i) + sep
            new_list.append(item)
    return new_list


def file_write(filename, a, b):
    """定义一个可以写入质数的函数"""
    try:
        with open(filename, 'w+', encoding='utf-8') as file:
            data = prime_numbers(a, b)
            data_str = num_str(data, ' ')
            for item in data_str:
                file.write(item)
    except IOError:
        print('读写文件发生错误')
    else:
        print('成功完成%d-%d之间质数的写入,保存在:%s' % (a, b-1, filename))


def file_read(filename):
    """定义一个输入文件名即可读取文件的函数,默认以‘r’模式打开"""
    with open(filename, 'r', encoding='utf-8') as file:
        read = file.readlines()
        print('%s的内容是:\n%s' % (filename, read))


if __name__ == '__main__':
    file_write('1-99.txt', 1, 100)
    file_write('100-999.txt', 100, 1000)
    file_write('1000-9999.txt', 1000, 10000)
    file_read('1-99.txt')
    file_read('100-999.txt')
    file_read('1000-9999.txt')

欢迎小伙伴指正~

  • 29
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值