文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

python3--文件操作

2023-01-30 21:58

关注

python文件操作

文件以什么编码存储,就以什么编码打开

参数:

1 文件路劲

2 编码方式

3 执行动作(打开方式):只读,只写,追加,读写,写读

例子

现有一个文档,制服护士空姐萝莉联系方式.txt,怎么用python打开?

f = open('D:\制服护士空姐萝莉联系方式.txt', encoding='gbk', mode='r')
content = f.read()
print(content)
f.close()

执行结果

没睡醒?赶紧去写代码吧。


上面例子讲解

f:变量 文件句柄

open 调用windows的系统功能,执行打开文件的动作

windows 默认编码方式:gbk,linux默认编码方式utf-8

r:  执行读的操作

f.close() 关闭文件

流程:打开一个文件,产生一个文件句柄,对文件句柄进行操作,关闭文件

读:

r,只读,以str方式读取

rb,只读,以bytes类型读取(非文字类的文件时,用rb,比如图片,音频文件等)

下面一个例子

f = open('D:\qycache\test.txt',encoding='utf-8')

content = f.read()

print(content)

f.close()

默认mode不写,表示只读模式


编码不一致时,报错

UnicodeDecodeError: 'gbk' codec can't decode byte 0xaa in position 14: illegal multibyte sequence

文件以什么编码存储的,就用什么编码打开


文件路径。

绝对路径:从根目录开始,一级一级查找直到找到文件

相对路径:在同一个文件夹下,直接写文件名即可

相对路径举例

f = open('username.txt',encoding='utf-8')

content = f.read()

print(content)

f.close()

务必保证python代码和txt文件在同一文件夹下


某些windows系统,读取文件的时候报错

[Error 22] Invalid argument: '\u202adD:\\xx.txt'

解决方法

第一种前面加个r:  r'C:\log.txt'

第二种前面多加个斜杠,表示转义:   C:\\log.txt



python r模式有5种模式读取

1:全部读出来f.read()

f = open('tianqi.txt',encoding='utf-8')

content = f.read()

print(content)

f.close()

执行输出

03月27日(今天)

晴转多云

11~27℃

西南风 1级

重度污染


2: 一行行的读f.readline()

f = open('天气.txt',encoding='utf-8')

print(f.readline())

print(f.readline())

print(f.readline())

f.close()


3: 将原文件的每一行作为一个列表的元素f.readlines()

f = open('天气.txt',encoding='utf-8')

print(f.readlines())

f.close()

执行输出

['03月27日(今天)\n', '晴转多云\n', '11~27℃\n', '西南风 1级\n', '重度污染']


4: 读取一部分read(n)

在r模式下,read(n)按照字符去读取

f = open('天气.txt',encoding='utf-8')

print(f.read(3))

f.close()

执行输出

03月


5:for循环读取(也是做好的一种方式)

f = open('天气.txt',encoding='utf-8')

for i in f:

    print(i.strip())

f.close()

执行输出

03月27日(今天)

晴转多云

11~27℃

西南风 1级

重度污染

在for循环中,每次读取一行,结束之后,内存就释放了。所以在整个for循环个过程中,始终只占用了一行内容的内存。

推荐使用第5种方式


写操作(w)

w 文件不存在时,创建一个文件写入内容

有文件时,将原文件内容清空,再写入内容

f = open('log.txt',encoding='utf-8',mode='w')

f.write('人生苦短,我想学Python')

f.close()


wb以bytes写入,写入的内容,必须要转换为bytes类型才可以


a追加

没有文件时,创建一个文件追加内容

有文件时,直接追加内容

f = open('log2.txt',encoding='utf-8',mode='a')

f.write('666')

f.close()


r+读写,先读,后追加

错误的写法

f = open('log.txt',encoding='utf-8',mode='r+')

f.write('BBB')

content = f.read()

print(content)

f.close()

执行输出,内容为空

为什么呢?

因为光标,默认是从0开始。只要进行一个动作,光标就会移动,包括读取。

上面的代码写入时,光标移动到最后了。所以执行f.read()时,读取不到后面的内容了。

r+ 一定要先读后写,否则会错乱或者读取不到内容


w+ 先写后读

f = open('log.txt',encoding='utf-8',mode='w+')

f.write('AAA')

content = f.read()

print(content)

f.close()

执行输出,内容是空的

写完之后,光标移动到最后了,所以读取的时候,读取不到内容了


正确的写法

f = open('log.txt',encoding='utf-8',mode='w+')

f.write('AAA')

print(f.tell()) #按直接去读光标位置

f.seek(0) #调整光标位置

content = f.read()

print(content)

f.close()

执行输出

3

AAA


下面一个例子

f = open('log.txt',encoding='utf-8',mode='w+')

f.write('中国')

print(f.tell()) #按直接去读光标位置

f.seek(2) #调整光标位置

content = f.read()

print(content)

f.close()

执行输出:

6

......

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xad in position 0: invalid start byte

因为一个中文占用3字节


ftp的断点续传,需要用到光标,一定会用到tell和seek


a+追加读,就不一一举例了

用的最多的还是r和r+模式,r的5种模式中,重点掌握第5种,for的方法


其它操作方法

其他操作方法:


truncate #截取文件

writable() #是否可写

readable() #是否可读


truncate是截取文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果

f = open('log.txt',encoding='utf-8',mode='r+')

# 截取10个字节

f.truncate(3)

content = f.read()

print(content)

f.close()

执行输出


判断是否可写

f = open('log.txt',encoding='utf-8',mode='r+')

print(f.writable())

f.close()

执行输出

True


回收方法为:

1、f.close() #回收操作系统级打开的文件,关闭文件句柄

2、del f #回收应用程序级的变量,在python代码级别中,删除变量


为了避免忘记回收文件句柄,需要使用with open方法,代码执行完毕之后,自动关闭文件句柄

功能1:自动关闭文件句柄

with open('log.txt',encoding='utf-8') as f:

    print(f.read())


功能2:一次性操作多个文件

with open('log.txt',encoding='utf-8') as f1,\

    open('log1.txt',encoding='utf-8',mode='r+') as f2:

    print(f1.read())

    print(f2.read())

有些情况下,必须先关闭,才能执行某某动作的情况下,不能用with,这种情况比较少见。

推荐使用with open


所有的软件,不是直接在原文件修改的。

它是进行了5步操作


1.将原文件读取到内存。

2.在内存中进行修改,形成新的内容。

3.将新的字符串写入新文件。

4.将原文件删除。

5.将新文件重命名成原文件。


将log文件内容中含有张三的,替换为李四

import os

#第1步

with open('log',encoding='utf-8') as f1,\

    open('log.bak',encoding='utf-8',mode='w') as f2:

    content = f1.read()

    #第2步

    new_content = content.replace('张三','李四')

    #第3步

    f2.write(new_content)

#第4步

os.remove('log')

#第5步

os.rename('log.bak','log')

这种方法不好,如果文件比较大,内存直接爆掉,因为f1.read()是将文件所有内容读取到内容中存放


推荐做法

import os

#第1步

with open('log',encoding='utf-8') as f1,\

    open('log.bak',encoding='utf-8',mode='w') as f2:

    for i in f1:

        #第3步

        new_i = i.replace('张三', '李四')

        #第4步

        f2.write(new_i)

#第4步

os.remove('log')

#第5步

os.rename('log.bak','log')

这种方式,每次只占用一行。

所有软件,都是执行这5步的


习题练习:

#!/usr/bin/env python
# coding: utf-8
__author__ = 'www.py3study.com'
# 1. 文件a.txt内容:每一行内容分别为商品名字,价钱,个数。
# apple 10 3
# tesla 100000 1
# mac 3000 2
# lenovo 30000 3
# chicken 10 3
# 通过代码,将其构建成这种数据类型:[{'name':'apple','price':10,'amount':3},{'name':'tesla','price':1000000,'amount':1}......] 并计算出总价钱。
#方法一
dic = {}
num = 0
sum1 = 0
with open('zuoye1.txt', encoding='utf-8', mode='r') as f1:
    for i in f1:
        ss = i.split()
        if ss[0] not in dic:
            num += 1
            dic['key' + str(num)] = {'name': ss[0], 'price': int(ss[1]), 'amount': int(ss[2])}
        else:
            dic['key' + str(num)] = {'name': ss[0], 'price': int(ss[1]), 'amount': int(ss[2])}

    print(list(dic.values()))
    for i in dic.values():
        sum1 += i['amount'] * i['price']
    print(sum1)

# 方法二
l1 = []
name_list = ['name', 'price', 'amount', 'year']
with open('zuoye1.txt', encoding='utf-8', mode='r') as f1:
    for i in f1:
        l2 = i.strip().split()
        #print(l2)
        dic = {}
        for j in range(len(l2)):
            dic[name_list[j]] = l2[j] # dic[name] = apple dic[price] = 10 .....
        l1.append(dic)
sum1 = 0
sum2 = 0
for i in l1:
    sum1 = int(i['amount']) * int(i['price'])
    sum2 += sum1
print(sum2)

# 3. 文件a1.txt内容:每一行内容分别为商品名字,价钱,个数。
# 文件内容:
# name:apple price:10 amount:3 year:2012
# name:tesla price:100000 amount:1 year:2013
#
# 通过代码,将其构建成这种数据类型:
# [{'name':'apple','price':10,'amount':3},
# {'name':'tesla','price':1000000,'amount':1}......]
# 并计算出总价钱。
# 思路 {key1 : {'name':'apple','price':10,'amount':3} ....}
dic = {}
num2 = 0
sum2 = 0
with open("zuoye3.txt", encoding='utf-8', mode='r') as f1:
    for i in f1:
        ss = i.strip().replace(' ', ':').split(':')
        #print(ss)
        num2 += 1
        if ss[0] not in dic:
            dic['key' + str(num2)] = {ss[0]: ss[1], ss[2]: ss[3], ss[4]: ss[5], ss[6]: ss[7]}
        else:
            dic['key' + str(num2)] = {ss[0]: ss[1], ss[2]: ss[3], ss[4]: ss[5], ss[6]: ss[7]}
    print(list(dic.values()))
    for i in dic.values():
        #print(i)
        sum2 += int(i['amount']) * int(i['price'])
    print("总价钱为:{}".format(sum2))
    
# 4,文件a2.txt内容:每一行内容分别为商品名字,价钱,个数。
# 文件内容:
# 序号     部门      人数      平均年龄      备注
# 1       python    30         26         单身狗
# 2       Linux     26         30         没对象
# 3       运营部     20         24         女生多
# 通过代码,将其构建成这种数据类型:
# [{'序号':'1','部门':Python,'人数':30,'平均年龄':26,'备注':'单身狗'},
# ......]
# 并计算出总价钱。
# 思路 {'序号':'1','部门':Python,'人数':30,'平均年龄':26,'备注':'单身狗'}
dic = {}
list1 = []
num = 0
sum4 = 0
with open("zuoye4.txt", encoding='utf-8', mode='r') as f1:
    for i in f1.readlines(1):
        ss = i.strip().split()
        for y in ss:
            list1.append(y.strip())
    for x in f1:
        x = x.split()
        num += 1
        if x[0] not in list1[0]:
            dic['key' + str(num)] = {list1[0]: x[0], list1[1]: x[1], list1[2]: x[2], list1[3]: x[3], list1[4]: x[4]}

    new_dic = list(dic.values())
    print(new_dic)
    for y in new_dic:
        sum4 += int(y['人数'])
    # 总人数
    print('总人数:{}'.format(sum4))

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯