python_文件处理

使用python进行文件处理

with open('pi_digits.txt') as file_object:
    contents=file_object.read()
    print  content

相比于原始文件,该输出唯一不同的地方是末尾多了一个空行。为何会多出这个空行呢?因为 read() 到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一
个空行。要删除多出来的空行,可在 print 语句中使用 rstrip() :

with open('pi_digits.txt') as file_object:
    contents = file_object.read()
    print(contents.rstrip())

由于文件夹 text_files 位于文件夹 python_work 中,因此可使用相对文件路 径来打开该文件夹中的文件。相对文件路径让 Python 到指定的位置去查找,而该位置是相对于当前运行的程
序所在目录的。在 Linux 和 OS X 中,你可以这样编写代码:

with open('text_files/filename.txt') as file_object:

这行代码让 Python 到文件夹 python_work 下的文件夹 text_files 中去查找指定的 .txt 文件。在 Windows 系统中,在文件路径中使用反斜杠( \ )而不是斜杠( / ):with open('text_files\filename.txt') as file_object:
你还可以将文件在计算机中的准确位置告诉 Python ,这样就不用关心当前运行的程序存储在什么地方了。这称为绝对文件路径 。在相对路径行不通时,可使用绝对路径。例如,
如果 text_files 并不在文件夹 python_work 中,而在文件夹 other_files 中,则向 open() 传递路径 ‘text_files/ filename.txt’ 行不通,因为 Python 只在文件夹 python_work 中查找
该位置。为明确地指出你希望 Python 到哪里去查找,你需要提供完整的路径。
绝对路径通常比相对路径更长,因此将其存储在一个变量中,再将该变量传递给 open() 会有所帮助。在 Linux 和 OS X 中,绝对路径类似于下面这样:


file_path = '/home/ehmatthes/other_files/text_files/filename.txt'
with open(file_path) as file_object:
而在 Windows 系统中,它们类似于下面这样:

file_path = 'C:\Users\ehmatthes\other_files\text_files\filename.txt'
with open(file_path) as file_object:

通过使用绝对路径,可读取系统任何地方的文件。就目前而言,最简单的做法是,要么将数据文件存储在程序文件所在的目录,要么将其存储在程序文件所在目录下的一个文件
夹(如 text_files )中。
注意 Windows 系统有时能够正确地解读文件路径中的斜杠。如果你使用的是 Windows 系统,且结果不符合预期,请确保在文件路径中使用的是反斜杠。

10.1.3  逐行读取
读取文件时,常常需要检查其中的每一行:你可能要在文件中查找特定的信息,或者要以某种方式修改文件中的文本。例如,你可能要遍历一个包含天气数据的文件,并使用天
气描述中包含字样 sunny 的行。在新闻报道中,你可能会查找包含标签  的行,并按特定的格式设置它。
要以每次一行的方式检查文件,可对文件对象使用 for 循环:
file_reader.py
❶ filename = 'pi_digits.txt'
❷
❸ with open(filename) as file_object:
for line in file_object:
print(line)
在❶处,我们将要读取的文件的名称存储在变量 filename 中,这是使用文件时一种常见的做法。由于变量 filename 表示的并非实际文件 —— 它只是一个让 Python 知道到哪里
去查找文件的字符串,因此可轻松地将 'pi_digits.txt' 替换为你要使用的另一个文件的名称。调用 open() 后,将一个表示文件及其内容的对象存储到了变
量 file_object 中(见❷)。这里也使用了关键字 with ,让 Python 负责妥善地打开和关闭文件。为查看文件的内容,我们通过对文件对象执行循环来遍历文件中的每一行(见
❸)。
我们打印每一行时,发现空白行更多了:
3.1415926535
8979323846
2643383279
为何会出现这些空白行呢?因为在这个文件中,每行的末尾都有一个看不见的换行符,而 print 语句也会加上一个换行符,因此每行末尾都有两个换行符:一个来自文件,另一
个来自 print 语句。要消除这些多余的空白行,可在 print 语句中使用 rstrip() :
filename = 'pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
print(line.rstrip())
现在,输出又与文件内容完全相同了:
3.1415926535
8979323846
2643383279
10.1.4  创建一个包含文件各行内容的列表
使用关键字 with 时, open() 返回的文件对象只在 with 代码块内可用。如果要在 with 代码块外访问文件的内容,可在 with 代码块内将文件的各行存储在一个列表中,并
在 with 代码块外使用该列表:你可以立即处理文件的各个部分,也可推迟到程序后面再处理。
下面的示例在 with 代码块中将文件 pi_digits.txt 的各行存储在一个列表中,再在 with 代码块外打印它们:
filename = 'pi_digits.txt'
❶
❷
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
❶处的方法 readlines() 从文件中读取每一行,并将其存储在一个列表中;接下来,该列表被存储到变量 lines 中;在 with 代码块外,我们依然可以使用这个变量。在❷
处,我们使用一个简单的 for 循环来打印 lines 中的各行。由于列表 lines 的每个元素都对应于文件中的一行,因此输出与文件内容完全一致。
10.1.5  使用文件的内容
将文件读取到内存中后,就可以以任何方式使用这些数据了。下面以简单的方式使用圆周率的值。首先,我们将创建一个字符串,它包含文件中存储的所有数字,且没有任何空
格:
pi_string.py
filename = 'pi_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
❶
❷
pi_string = ''
for line in lines:pi_string += line.rstrip()
❸
print(pi_string)
print(len(pi_string))
就像前一个示例一样,我们首先打开文件,并将其中的所有行都存储在一个列表中。在❶处,我们创建了一个变量 —— pi_string ,用于存储圆周率的值。接下来,我们使用
一个循环将各行都加入 pi_string ,并删除每行末尾的换行符(见❷)。在❸处,我们打印这个字符串及其长度:
3.1415926535 8979323846 2643383279
36
在变量 pi_string 存储的字符串中,包含原来位于每行左边的空格,为删除这些空格,可使用 strip() 而不是 rstrip() :
filename = 'pi_30_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.strip()
print(pi_string)
print(len(pi_string))
这样,我们就获得了一个这样的字符串:它包含精确到 30 位小数的圆周率值。这个字符串长 32 字符,因为它还包含整数部分的 3 和小数点:
3.141592653589793238462643383279
32
注意  读取文本文件时, Python 将其中的所有文本都解读为字符串。如果你读取的是数字,并要将其作为数值使用,就必须使用函数 int() 将其转换为整数,或使用
函数 float() 将其转换为浮点数。
10.1.6  包含一百万位的大型文件
前面我们分析的都是一个只有三行的文本文件,但这些代码示例也可处理大得多的文件。如果我们有一个文本文件,其中包含精确到小数点后 1 000 000 位而不是 30 位的圆周率
值,也可创建一个包含所有这些数字的字符串。为此,我们无需对前面的程序做任何修改,只需将这个文件传递给它即可。在这里,我们只打印到小数点后 50 位,以免终端为显
示全部 1 000 000 位而不断地翻滚:
pi_string.py
filename = 'pi_million_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.strip()
print(pi_string[:52] + "...")
print(len(pi_string))
输出表明,我们创建的字符串确实包含精确到小数点后 1 000 000 位的圆周率值:
3.14159265358979323846264338327950288419716939937510...
1000002
对于你可处理的数据量, Python 没有任何限制;只要系统的内存足够多,你想处理多少数据都可以。
注意  要运行这个程序(以及后面的众多示例),你需要从 https://www.nostarch.com/pythoncra-shcourse/ 下载相关的资源。
10.1.7  圆周率值中包含你的生日吗
我一直想知道自己的生日是否包含在圆周率值中。下面来扩展刚才编写的程序,以确定某个人的生日是否包含在圆周率值的前 1 000 000 位中。为此,可将生日表示为一个由数字
组成的字符串,再检查这个字符串是否包含在 pi_string 中:
filename = 'pi_million_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.rstrip()
❶
❷
birthday = input("Enter your birthday, in the form mmddyy: ")
if birthday in pi_string:
print("Your birthday appears in the first million digits of pi!")
else:
print("Your birthday does not appear in the first million digits of pi.")
在❶处,我们提示用户输入其生日,在接下来的❷处,我们检查这个字符串是否包含在 pi_string 中。运行一下这个程序:Enter your birthdate, in the form mmddyy: 120372
Your birthday appears in the first million digits of pi!
我的生日确实出现在了圆周率值中!读取文件的内容后,就可以以你能想到的任何方式对其进行分析。
动手试一试
10-1 Python 学习笔记 :在文本编辑器中新建一个文件,写几句话来总结一下你至此学到的 Python 知识,其中每一行都以 “In Python you can” 打头。将这个文件命名为
learning_python.txt ,并将其存储到为完成本章练习而编写的程序所在的目录中。编写一个程序,它读取这个文件,并将你所写的内容打印三次:第一次打印时读取整个
文件;第二次打印时遍历文件对象;第三次打印时将各行存储在一个列表中,再在 with 代码块外打印它们。
10-2 C 语言学习笔记 :可使用方法 replace() 将字符串中的特定单词都替换为另一个单词。下面是一个简单的示例,演示了如何将句子中的 'dog' 替换为 'cat'
:
>>> message = "I really like dogs."
>>> message.replace('dog', 'cat')
'I really like cats.'
读取你刚创建的文件 learning_python.txt 中的每一行,将其中的 Python 都替换为另一门语言的名称,如 C 。将修改后的各行都打印到屏幕上。
10.2  写入文件
保存数据的最简单的方式之一是将其写入到文件中。通过将输出写入文件,即便关闭包含程序输出的终端窗口,这些输出也依然存在:你可以在程序结束运行后查看这些输出,
可与别人分享输出文件,还可编写程序来将这些输出读取到内存中并进行处理。
10.2.1  写入空文件
要将文本写入文件,你在调用 open() 时需要提供另一个实参,告诉 Python 你要写入打开的文件。为明白其中的工作原理,我们来将一条简单的消息存储到文件中,而不是将其打
印到屏幕上:
write_message.py
filename = 'programming.txt'
❶
❷
with open(filename, 'w') as file_object:
file_object.write("I love programming.")
在这个示例中,调用 open() 时提供了两个实参(见❶)。第一个实参也是要打开的文件的名称;第二个实参( 'w' )告诉 Python ,我们要以写入模式 打开这个文件。打开文件
时,可指定读取模式 ( 'r' )、写入模式 ( 'w' )、附加模式 ( 'a' )或让你能够读取和写入文件的模式( 'r+' )。如果你省略了模式实参, Python 将以默认的只读模式打
开文件。
如果你要写入的文件不存在,函数 open() 将自动创建它。然而,以写入( 'w' )模式打开文件时千万要小心,因为如果指定的文件已经存在, Python 将在返回文件对象前清空
该文件。
在❷处,我们使用文件对象的方法 write() 将一个字符串写入文件。这个程序没有终端输出,但如果你打开文件 programming.txt ,将看到其中包含如下一行内容:
programming.txt
I love programming.
相比于你的计算机中的其他文件,这个文件没有什么不同。你可以打开它、在其中输入新文本、复制其内容、将内容粘贴到其中等。
注意   Python 只能将字符串写入文本文件。要将数值数据存储到文本文件中,必须先使用函数 str() 将其转换为字符串格式。
10.2.2  写入多行
函数 write() 不会在你写入的文本末尾添加换行符,因此如果你写入多行时没有指定换行符,文件看起来可能不是你希望的那样:
filename = 'programming.txt'
with open(filename, 'w') as file_object:
file_object.write("I love programming.")
file_object.write("I love creating new games.")
如果你打开 programming.txt ,将发现两行内容挤在一起:
I love programming.I love creating new games.
要让每个字符串都单独占一行,需要在 write() 语句中包含换行符:
filename = 'programming.txt'
with open(filename, 'w') as file_object:
file_object.write("I love programming.\n")
file_object.write("I love creating new games.\n")
现在,输出出现在不同行中:I love programming.
I love creating new games.
像显示到终端的输出一样,还可以使用空格、制表符和空行来设置这些输出的格式。
10.2.3  附加到文件
如果你要给文件添加内容,而不是覆盖原有的内容,可以附加模式 打开文件。你以附加模式打开文件时, Python 不会在返回文件对象前清空文件,而你写入到文件的行都将添加
到文件末尾。如果指定的文件不存在, Python 将为你创建一个空文件。
下面来修改 write_message.py ,在既有文件 programming.txt 中再添加一些你酷爱编程的原因:
write_message.py
filename = 'programming.txt'
❶
❷
with open(filename, 'a') as file_object:
file_object.write("I also love finding meaning in large datasets.\n")
file_object.write("I love creating apps that can run in a browser.\n")
在❶处,我们打开文件时指定了实参 'a' ,以便将内容附加到文件末尾,而不是覆盖文件原来的内容。在❷处,我们又写入了两行,它们被添加到文件 programming.txt 末尾:
programming.txt
I
I
I
I
love
love
also
love
programming.
creating new games.
love finding meaning in large datasets.
creating apps that can run in a browser.
最终的结果是,文件原来的内容还在,它们后面是我们刚添加的内容。
动手试一试
10-3 访客 :编写一个程序,提示用户输入其名字;用户作出响应后,将其名字写入到文件 guest.txt 中。
10-4 访客名单 :编写一个 while 循环,提示用户输入其名字。用户输入其名字后,在屏幕上打印一句问候语,并将一条访问记录添加到文件 guest_book.txt 中。确保这
个文件中的每条记录都独占一行。
10-5 关于编程的调查 :编写一个 while 循环,询问用户为何喜欢编程。每当用户输入一个原因后,都将其添加到一个存储所有原因的文件中。

你可能感兴趣的:(python_文件处理)