【Python教程11】-文件

11、Python 教程 - 文件

打开文件

当前目录中有一个名为 beyond.txt 的文本文件,打开该文件调用 open 时,原本可以不指定模式,因为其默认值就是'r'。

text 复制代码
import io
f = open('beyond.txt')

文件模式

描述
'r' 读取模式(默认值)
'w' 写入模式
'x' 独占写入模式
'a' 附加模式
'b' 二进制模式(与其他模式结合使用)
't' 文本模式(默认值,与其他模式结合使用)
'+' 读写模式(与其他模式结合使用)

文件的基本方法

读取和写入

在当前路径下创建一个 beyond.txt 文本文件,在该文本文件中写入内容,并读取出来。

text 复制代码
import io
f = open('beyond.txt','w')
f.write("I like beyond band")#结果为:18
f.write("I like wsq")#结果为:10
f.close()

运行结果如下:

text 复制代码
import io
f = open('beyond.txt','r')
f.read(4)#结果为:'I li'
f.read()#结果为:'ke beyond bandI like wsq'

首先,指定了要读取多少(4)个字符。接下来,读取了文件中余下的全部内容(不指定要读取多少个字符)。

使用管道重定向输出

在 bash 等 shell 中,可依次输入多个命令,并使用管道将它们链接起来**$cat beyond.txt | python somescript.py | sort**

catbeyond.txt:将文件 beyond.txt 的内容写入到标准输出(sys.stdout)。

python somescript.py:执行 Python 脚本 somescript。这个脚本从其标准输入中读取,并将结果写入到标准输出。

sort:读取标准输入(sys.stdin)中的所有文本,将各行按字母顺序排序,并将结果写入到标准输出。

somescript.py 从其 sys.stdin 中读取数据(这些数据是 beyond.txt 写入的),并将结果写入到其 sys.stdout(sort 将从这里获取数据)。
计算 sys.stdin 中包含多少个单词的简单脚本 somescript.py 代码如下:

text 复制代码
# somescript.py
import sys
text = sys.stdin.read()
words = text.split()
wordcount = len(words)
print('Wordcount:',wordcount)

beyond.txt 内容如下:

text 复制代码
Yellow Skies, I can see the Yellow Skies.
See you again, I see you again
In my dreams, in my dreams, in my dreams, in my dreams.
Morning light, I remember morning light.
Outside my doors, I ll see you no more.
In my dreams, in my dreams, in my dreams, in my dreams
Forever, Forever Ill be forever holding you.
Forever, Forever Ill be forever holding you.
Responsible, Responsible, Responsible, Responsible.
So black and white,
Its become so black and white.

cat beyond.txt | python somescript.py
随机存取 所有的文件都可以当成流来进行处理,可以在文件中进行移动,这称为随机存取。可使用文件对象的两个方法:seek 和 tell。

方法 seek(offset[, whence]) 将当前位置(执行读取或写入的位置)移到 offset 和 whence 指定的地方。参数 offset 指定了字节(字符)数参数 whence 默认为 io.SEEK_SET(0),这意味着偏移量是相对于文件开头的(偏移量不能为负数)。

text 复制代码
import io
f = open(r'E:\Jupyter_workspace\study\python\book\beyond.txt','w')
f.write('beyondhelloword')#结果为:15
f.seek(5)#结果为:5
f.write('hello beyond')#结果为:12
f.read()#结果为:'beyonhello beyond'
#seek(5)此时的指向了d,再次进行write操作,则会覆盖之后的所有
text 复制代码
import io
f = open(r'E:\Jupyter_workspace\study\python\book\beyond.txt')
f.read(3)#结果为:'bey'
f.read(2)#结果为:'on'
f.tell()#结果为:5
#这里的tell方法返回的是此时指向的位置

读取和写入行

读取一行(从当前位置到下一个分行符的文本),可使用方法​readline ​。可不提供任何参数(在这种情况下,将读取一行并返回它)也可提供一个非负整数,指定 readline 最多可读取多少个字符。

方法​writelines ​:接受一个字符串列表(实际上,可以是任何序列或可迭代对象),并将这些字符串都写入到文件(或流)中。写入时 不会添加换行符,因此你必须自行添加。另外,没有方法writeline,因为可以使用 write。

关闭文件

方法 close 将文件关闭在 python 中运行的而结果会存入到缓冲区中,有可能没有将结果给你进行立即返回,通常程序退出时将自动关闭文件对象,并将缓冲器的内容给返回。当然如果不想关闭文件,又想将缓冲器的内容及时得到,可以使用 flush 方法。

当然也可以使用 try/finally 语句,并在 finally 子句中调用 close。

text 复制代码
import io
f = open(r'E:\Jupyter_workspace\study\python\book\beyond.txt','w')
try:
    f.write('like wsq')
finally:
    f.close()

有一条专门为此设计的语句,那就是 with 语句,这样是用的最多的方法

text 复制代码
import io
with open(r'E:\Jupyter_workspace\study\python\book\beyond.txt','w') as f:
    f.write('like qibao')

上下文管理器 with 语句实际上是一个非常通用的结构,允许你使用所谓的​上下文管理器 ​。上下文管理器是支持两个方法的对象:__enter____exit__。方法__enter__不接受任何参数,在进入 with 语句时被调用,其返回值被赋给关键字 as 后面的变量。方法__exit__接受三个参数:异常类型、异常对象和异常跟踪。它在离开方法时被调用(通过前述参数将引发的异常提供给它)。如果__exit__返回 False,将抑制所有的异常.

使用文件的基本方法

beyond.txt 内容如下:

text 复制代码
Yellow Skies, I can see the Yellow Skies.
See you again, I see you again
In my dreams, in my dreams, in my dreams, in my dreams.
Morning light, I remember morning light.
Outside my doors, I ll see you no more.
In my dreams, in my dreams, in my dreams, in my dreams
Forever, Forever Ill be forever holding you.
Forever, Forever Ill be forever holding you.
Responsible, Responsible, Responsible, Responsible.
So black and white,
Its become so black and white.

read(n)

text 复制代码
import io
f = open(r'E:\Jupyter_workspace\study\python\book\beyond.txt')
f.read(7)#结果为:'Yellow '
f.read(4)#结果为:'Skie'
f.close()

read()

text 复制代码
import io
f = open(r'E:\Jupyter_workspace\study\python\book\beyond.txt')
print(f.read())#结果为:
'''
Yellow Skies, I can see the Yellow Skies.
See you again, I see you again
In my dreams, in my dreams, in my dreams, in my dreams.
Morning light, I remember morning light.
Outside my doors, I ll see you no more.
In my dreams, in my dreams, in my dreams, in my dreams
Forever, Forever Ill be forever holding you.
Forever, Forever Ill be forever holding you.
Responsible, Responsible, Responsible, Responsible.
So black and white,
Its become so black and white.
'''
f.close()

readline()

text 复制代码
import io
f = open(r'E:\Jupyter_workspace\study\python\book\beyond.txt')
for i in range(3):
    print(str(i)+':'+f.readline(),end='')#结果为:
'''
0:Yellow Skies, I can see the Yellow Skies.
1:See you again, I see you again
2:In my dreams, in my dreams, in my dreams, in my dreams.
'''
f.close()

readlines()

text 复制代码
import io
import pprint
pprint.pprint(open(r'E:\Jupyter_workspace\study\python\book\beyond.txt').readlines())#结果为:
'''
['Yellow Skies, I can see the Yellow Skies.\n',
 'See you again, I see you again\n',
 'In my dreams, in my dreams, in my dreams, in my dreams.\n',
 'Morning light, I remember morning light.\n',
 'Outside my doors, I ll see you no more.\n',
 'In my dreams, in my dreams, in my dreams, in my dreams\n',
 'Forever, Forever Ill be forever holding you.\n',
 'Forever, Forever Ill be forever holding you.\n',
 'Responsible, Responsible, Responsible, Responsible.\n',
 'So black and white,\n',
 'Its become so black and white.']
'''
#这里利用了文件对象将被自动关闭这一事实。

write(string)

text 复制代码
import io
f = open(r'E:\Jupyter_workspace\study\python\book\beyond.txt','w')
f.write('I\nlike\nwsq\n')#结果为:11
f.close()

writelines(list)

text 复制代码
import io
f = open(r'E:\Jupyter_workspace\study\python\book\beyond.txt')
lines = f.readlines()
f.close()
lines[1] = "am\n"
f = open(r'E:\Jupyter_workspace\study\python\book\beyond.txt', 'w')
f.writelines(lines)
f.close()

迭代文件内容

使用 read 遍历字符

text 复制代码
import io
def beyond(string):
    print("words is:",string)
with open(r'E:\Jupyter_workspace\study\python\book\beyond.txt') as f:
    char = f.read(1)
    while char:
        beyond(char)
        char = f.read(1)
'''
words is: I
words is: 
words is: a
words is: m
words is: 
words is: w
words is: s
words is: q
words is: 
'''
'''
这个程序之所以可行,是因为到达文件末尾时,方法read将返回一个空字符串,
但在此之前,返回的字符串都只包含一个字符(对应于布尔值True)。
只要char为True,你就知道还没结束。
'''

以不同的方式编写循环

text 复制代码
import io
def beyond(string):
    print("words is:",string)
with open(r'E:\Jupyter_workspace\study\python\book\beyond.txt') as f:
    while True:
        char = f.read(1)
        if not char:
            break
        beyond(char)
'''
words is: I
words is: 
words is: a
words is: m
words is: 
words is: w
words is: s
words is: q
words is: 
'''

每次一行 处理文本文件时,通常想做的是迭代其中的​ ​,而不是每个字符。方法 readline,可像迭代字符一样轻松地迭代行。
在 while 循环中使用 readline

text 复制代码
import io
def beyond(string):
    print("words is:",string)
with open(r'E:\Jupyter_workspace\study\python\book\beyond.txt') as f:
    while True:
        line = f.readline()
        if not line:
            break
        beyond(line)
'''
words is: I
words is: am
words is: wsq
'''

读取所有内容

使用 read 迭代字符

text 复制代码
import io
def beyond(string):
    print("words is:",string)
with open(r'E:\Jupyter_workspace\study\python\book\beyond.txt') as f:
    for char in f.read():
        beyond(char)
'''
words is: I
words is: 
words is: a
words is: m
words is: 
words is: w
words is: s
words is: q
words is: 
'''

使用 readlines 迭代行

text 复制代码
import io
def beyond(string):
    print("words is:",string)
with open(r'E:\Jupyter_workspace\study\python\book\beyond.txt') as f:
    for line in f.readlines():
        beyond(line)
'''
words is: I
words is: am
words is: wsq
'''

使用 fileinput 实现延迟行迭代

有时候需要迭代大型文件中的行,此时使用 readlines 将占用太多内存。在 Python 中,在可能的情况下,应首选 for 循环。可使用一种名为延迟行迭代 的方法------说它延迟是因为它只读取实际需要的文本部分。
使用 fileinput 迭代行

text 复制代码
import fileinput
import io
def beyond(string):
    print("words is:",string)
for line in fileinput.input(r'E:\Jupyter_workspace\study\python\book\beyond.txt'):
    beyond(line)
'''
words is: I
words is: am
words is: wsq
'''

文件迭代器

迭代文件

text 复制代码
import io
def beyond(string):
    print("words is:",string)
with open(r'E:\Jupyter_workspace\study\python\book\beyond.txt') as f:
    for line in f:
        beyond(line)
'''
words is: I
words is: am
words is: wsq
'''

在不将文件对象赋给变量的情况下迭代文件

text 复制代码
import io
def beyond(string):
    print("words is:",string)
for line in open(r'E:\Jupyter_workspace\study\python\book\beyond.txt'):
    beyond(line)
'''
words is: I
words is: am
words is: wsq
'''

与其他文件一样,sys.stdin 也是可迭代的

text 复制代码
import sys
import io
def beyond(string):
    print("words is:",string)
for line in sys.stdin:
    beyond(line)

对迭代器做的事情基本上都可对文件做

text 复制代码
f = open(r'E:\Jupyter_workspace\study\python\book\beyond.txt', 'w') 
print('First', 'line', file=f)
print('Second', 'line', file=f)
print('Third', 'and final', 'line', file=f)
f.close()
lines = list(open(r'E:\Jupyter_workspace\study\python\book\beyond.txt'))
lines#结果为:['First line\n', 'Second line\n', 'Third and final line\n']
first, second, third = open(r'E:\Jupyter_workspace\study\python\book\beyond.txt')
first#结果为:'First line\n'
second#结果为:'Second line\n'
third#结果为:'Third and final line\n'

**注意:**1,使用了 print 来写入文件,这将自动在提供的字符串后面添加换行符。2,对打开的文件进行序列解包,从而将每行存储到不同的变量中。3,写入文件后将其关闭,以确保数据得以写入磁盘。

小结

概念 描述
类似于文件的对象 类似于文件的对象是支持 read 和 readline(可能还有 write 和 writelines)等方法的对象。
打开和关闭文件 要打开文件,可使用函数 open,并向它提供一个文件名。如果要确保即便发生错误时文件也将被关闭,可使用 with 语句。
模式和文件类型 打开文件时,还可指定模式,如'r'(读取模式)或'w'(写入模式)通过在模式后面加上'b',可将文件作为二进制文件打开,并关闭 Unicode 编码和换行符替换。
标准流 三个标准流(模块 sys 中的 stdin、stdout 和 stderr)都是类似于文件的对象,它们实现了 UNIX 标准 I/O 机制(Windows 也提供了这种机制)。
读取和写入 要从文件或类似于文件的对象中读取,可使用方法 read;要执行写入操作,可使用方法 write。
读取和写入行 要从文件中读取行,可使用 readline 和 readlines;要写入行,可使用 writelines。
迭代文件内容 迭代文件内容的方法很多,其中最常见的是迭代文本文件中的行,这可通过简单地对文件本身进行迭代来做到。还有其他与较旧 Python 版本兼容的方法,如使用 readlines。

本章介绍的新函数

函数 描述
open(name, ...) 打开文件并返回一个文件对象
相关推荐
先做个垃圾出来………2 小时前
SortedList(2)
开发语言
云栖梦泽2 小时前
易语言开发从入门到精通:补充篇·文件批量操作深度实战·常用格式处理·自动化脚本开发·性能优化
开发语言
Big Cole2 小时前
PHP面试题(核心基础篇:垃圾回收+自动加载)
android·开发语言·php
2301_822375442 小时前
Python虚拟环境(venv)完全指南:隔离项目依赖
jvm·数据库·python
m0_706653232 小时前
跨语言调用C++接口
开发语言·c++·算法
2301_790300962 小时前
Python类型提示(Type Hints)详解
jvm·数据库·python
小罗和阿泽2 小时前
复习 Java(2)
java·开发语言
无小道2 小时前
Qt——信号槽
开发语言·qt
老骥伏枥~2 小时前
C# if / else 的正确写法与反例
开发语言·c#