目录 | 上一节 (1.5 列表) | 下一节 (1.7 函数)
1.6 文件治理
大多数的程序须要从某处读取输出。本节探讨文件拜访。
文件输出和输入
关上一个文件:
f = open('foo.txt', 'rt') # Open for reading (text)
g = open('bar.txt', 'wt') # Open for writing (text)
读取所有的数据:
data = f.read()
# Read only up to 'maxbytes' bytes
data = f.read([maxbytes])
写入一些文本:
g.write('some text')
当你实现操作后,敞开文件:
f.close()
g.close()
文件应该被正确地敞开,这是很容易遗记的一个步骤。因而,首选办法是像上面这样应用 with
语句:
with open(filename, 'rt') as file:
# Use the file `file`
...
# No need to close explicitly
...statements
当控制流来到缩进的代码块时,这将会主动敞开文件。
读取文件数据的习惯用法
以字符串的模式一次性读取整个文件:
with open('foo.txt', 'rt') as file:
data = file.read()
# `data` is a string with all the text in `foo.txt`
通过迭代逐行读取文件:
with open(filename, 'rt') as file:
for line in file:
# Process the line
写入文件的习惯用法
写入字符串数据:
with open('outfile', 'wt') as out:
out.write('Hello World\n')
...
重定向 print() 函数:
with open('outfile', 'wt') as out:
print('Hello World', file=out)
...
练习
本练习依赖于 Data/portfolio.csv
文件。该文件由一行一行的对于股票投资组合的信息形成。假设你是在 practical-python/Work/
目录下进行操作。如果你不确定本人所在的目录,你能够通过执行以下操作找出 Python 运行的目录:
>>> import os
>>> os.getcwd()
'/Users/beazley/Desktop/practical-python/Work' # Output vary
>>>
练习 1.26: 文件预览
首先,尝试以字符串的模式一次性读取整个文件:
>>> with open('Data/portfolio.csv', 'rt') as f:
data = f.read()
>>> data
'name,shares,price\n"AA",100,32.20\n"IBM",50,91.10\n"CAT",150,83.44\n"MSFT",200,51.23\n"GE",95,40.37\n"MSFT",50,65.10\n"IBM",100,70.44\n'
>>> print(data)
name,shares,price
"AA",100,32.20
"IBM",50,91.10
"CAT",150,83.44
"MSFT",200,51.23
"GE",95,40.37
"MSFT",50,65.10
"IBM",100,70.44
>>>
在下面的示例中,应留神 Python 有两种输入模式。在第一种模式下,你在提示符后输出 data
,Python 向你展现蕴含引号和本义码的原始字符串。当你输出 print(data)
时,你取得真正的字符串的格式化输入。
一次性读取文件很简略,但这通常不是最失当的读取文件形式——尤其是当文件碰巧很大或者文件蕴含要一次性解决的文本行时。
要逐行读取文件,能够像上面这样应用 for 循环:
>>> with open('Data/portfolio.csv', 'rt') as f:
for line in f:
print(line, end='')
name,shares,price
"AA",100,32.20
"IBM",50,91.10
...
>>>
当你像下面展现的那样应用此代码时,它会读取文件的每一行,直到达到文件开端。在文件开端,循环会进行。
在某些特定的状况下,你可能想要手动的读取或者跳过某一行文本(例如,可能你想跳过列题目的第一行):
>>> f = open('Data/portfolio.csv', 'rt')
>>> headers = next(f)
>>> headers
'name,shares,price\n'
>>> for line in f:
print(line, end='')"AA",100,32.20"IBM",50,91.10
...
>>> f.close()
>>>
next()
函数返回文件中的下一行文本。如果你重复调用该函数,将会取得间断的行。然而,如你所知,for
循环曾经应用 next()
函数获取数据了。所以,通常状况下,除非你像下面展现的那样试图显式跳过或者读取一行,否则,不要间接调用 next()
函数。
一旦读取文件的各行,你就能够开始执行更多的操作,例如拆分。
示例,尝试以下操作:
>>> f = open('Data/portfolio.csv', 'rt')
>>> headers = next(f).split(',')
>>> headers
['name', 'shares', 'price\n']
>>> for line in f:
row = line.split(',')
print(row)
['"AA"', '100', '32.20\n']
['"IBM"', '50', '91.10\n']
...
>>> f.close()
留神:在这些示例中,因为没有应用 with
语句,所以 f.close()
被显式的调用。
练习 1.27: 读取数据文件
当初你曾经晓得如何读取文件,让咱们编写一个程序来执行简略的计算。
portfolio.csv
文件外面的列对应股票的名称,股票的数量以及单支股票持有的购买价格。编写一个名为 pcost.py
的程序来关上这个文件,读取所有的行并且计算在所有的股票投资组合中破费多少钱来购买这些股份。
提醒:要将字符串转为整数,应用 int()
函数。要将字符串转为浮点数,应用 float()
函数。
你的程序应该打印如下输入:
Total cost 44671.15
练习 1.28: 其它类型的“文件 ”
如果你想读取非文本文件(如 gzip 压缩的数据文件)怎么办?尽管内建 open()
函数在这里帮不了你了,然而 Python 提供的 gzip
模块能够读取 gzip 文件。
试试看:
>>> import gzip
>>> with gzip.open('Data/portfolio.csv.gz', 'rt') as f:
for line in f:
print(line, end='')
... look at the output ...
>>>
留神:此处蕴含 'rt'
文件模式至关重要。如果你遗记应用它,你将会失去字节字符串而不是通常的文本字符串。
阐明: 咱们不应该为此应用 Pandas 吗?
数据科学家很快指出,诸如 Pandas 这样的库曾经具备读取 CSV 文件的函数,为什么不应用 Pandas 呢? 的确如此——而且成果也很好。然而,这不是一门无关学习 Pandas 的课程,读取文件是一个比读取 CSV 文件更广泛的问题。咱们应用 CSV 文件做例子的次要起因是:它是大多数编码人员相熟的格局,并且绝对易于间接应用——在读取 CSV 文件的过程中,说明了许多 Python 个性。所以,当你回到工作中,请务必应用 Pandas。然而,在本课程剩下局部,咱们将会持续应用规范的 Python 函数。
目录 | 上一节 (1.5 列表) | 下一节 (1.7 函数)
注:残缺翻译见 https://github.com/codists/practical-python-zh