Python 学习笔记 7. 输入输出
有几种方法可以显示程序的输出;数据可以以人类可读的形式打印出来,或者写入文件以供将来使用。
7.1. 更漂亮的输出格式
使用 格式字字符串字面值
python>>> year = 2016 >>> event = 'Referendum' >>> f'Results of the {year} {event}' 'Results of the 2016 Referendum' >>> F'Results of the {year} {event}' 'Results of the 2016 Referendum'
使用 str.format() 方法
python>>> yes_votes = 42_572_654 >>> no_votes = 43_132_495 >>> percentage = yes_votes / (yes_votes + no_votes) >>> '{:-9} YES votes {:2.2%}'.format(yes_votes, percentage) ' 42572654 YES votes 49.67%'
str()
函数是用于返回人类可读的值的表示,而 repr()
是用于生成解释器可读的表示。
>>> s = 'Hello, world.'
>>> str(s)
'Hello, world.'
>>> repr(s)
"'Hello, world.'"
7.1.1. 格式化字符串文字
可选的格式说明符可以跟在表达式后面(:格式)。
>>> import math
>>> print(f'The value of pi is approximately {math.pi:.3f}.')
The value of pi is approximately 3.142.
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
... print(f'{name:10} ==> {phone:10d}')
...
Sjoerd ==> 4127
Jack ==> 4098
Dcab ==> 7678
'!a'
应用 ascii()
,'!s'
应用 str()
,还有 '!r'
应用 repr()
:
>>> animals = 'eels'
>>> print(f'My hovercraft is full of {animals}.')
My hovercraft is full of eels.
>>> print(f'My hovercraft is full of {animals!s}.')
My hovercraft is full of eels.
>>> print(f'My hovercraft is full of {animals!r}.')
My hovercraft is full of 'eels'.
>>> print(f'My hovercraft is full of {animals!a}.')
My hovercraft is full of 'eels'.
7.1.2. 字符串的 format() 方法
>>> print('We are the {} who say "{}!"'.format('knights', 'Ni'))
We are the knights who say "Ni!"
>>> print('{1} and {0}'.format('spam', 'eggs'))
eggs and spam
>>> print('This {food} is {adjective}.'.format(food='spam', adjective='absolutely horrible'))
This spam is absolutely horrible.
>>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', other='Georg'))
The story of Bill, Manfred, and Georg.
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; Dcab: {0[Dcab]:d}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
>>> for x in range(1, 11):
... print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
7.1.3. 手动格式化字符串
>>> for x in range(1, 11):
... print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
... # Note use of 'end' on previous line
... print(repr(x*x*x).rjust(4))
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
str.rjust()
方法通过在左侧填充空格来对给定宽度的字段中的字符串进行右对齐。
类似的方法还有:
str.ljust()
str.center()
str.zfill()
左补零
7.1.4. 旧的字符串格式化方法
%
操作符也可以用作字符串格式化。更多格式见 这里。
>>> import math
>>> print('The value of pi is approximately %5.3f.' % math.pi)
The value of pi is approximately 3.142.
>>> print('The value of pi is approximately %5.5f.' % math.pi)
The value of pi is approximately 3.14159.
7.2. 读写文件
open()
返回一个 file object,最常用的有两个参数: open(filename, mode)
。
>>> f = open('workfile', 'w')
filename : 文件名
mode : 文件使用方式
mode 参数是可选的;省略时默认为 'r'。
- 'r' 表示文件只能读取;
- 'w' 表示只能写入(已存在的同名文件会被删除);
- 'a' 表示打开文件以追加内容,任何写入的数据会自动添加到文件的末尾;
- 'r+' 表示打开文件进行读写。
通常文件是以 text mode 打开的,这意味着从文件中读取或写入字符串时,都会以指定的编码方式进行编码。如果未指定编码格式,默认值与平台相关 (参见 open())。
在 mode 中追加的 'b' 则以 binary mode 打开文件:现在数据是以字节对象的形式进行读写的。这个模式应该用于所有不包含文本的文件。
在文本模式下读取时,默认会把平台特定的行结束符 (Unix 上的 \n
, Windows 上的 \r\n
) 转换为 \n
。
在文本模式下写入时,默认会把出现的 \n
转换回平台特定的结束符。
在处理文件对象时,最好使用 with 关键字。
>>> with open('workfile') as f:
... read_data = f.read()
...
>>> # We can check that the file has been automatically closed.
... f.closed
True
关闭文件对象后,尝试使用该文件对象将自动失败。
>>> f.close()
>>> f.read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.
7.2.1. 文件对象的方法
1. f.read(size)
size 是一个可选的数值参数。当 size 被省略或者为负数时,将读取并返回整个文件的内容;如果文件的大小是你的机器内存的两倍就会出现问题。
当取其他值时,将读取并返回至多 size 个字符(在文本模式下)或 size 个字节(在二进制模式下)。
如果已到达文件末尾,f.read()
将返回一个空字符串 (''
)。
2. f.readline()
从文件中读取一行;换行符(\n
)留在字符串的末尾,如果文件不以换行符结尾,则在文件的最后一行省略。
>>> f = open('workfile', 'r')
>>> for line in f:
... print(line, end='')
...
This is the first line of the file.
Second line of the file
3. list(f)
以列表的形式读取文件中的所有行
>>> lines = list(f)
>>> for line in lines:
... print(line, end='')
...
This is the first line of the file.
Second line of the file
4. f.readlines()
以列表的形式读取文件中的所有行
>>> lines = f.readlines()
>>> for line in lines:
... print(line, end='')
...
This is the first line of the file.
Second line of the file
5. f.write(string)
>>> f.write('This is a test\n')
15
6. f.tell()
>>> f.tell()
62
7. f.seek(offset, whence)
在文本文件(那些在模式字符串中没有 b 的打开的文件)中,只允许相对于文件开头搜索(使用 seek(0, 2)
搜索到文件末尾是个例外)并且唯一有效的 offset 值是那些能从 f.tell()
中返回的或者是零。其他 offset 值都会产生未定义的行为。
offset
- 偏移位置(可以为负值)
whence
- 0:从文件开头起算
- 1:使用当前文件位置
- 2:使用文件末尾作为参考点
7.2.2. 使用 json 保存结构化数据
json.dumps()
序列化对象为字符串。
>>> import json
>>> json.dumps([1, 'simple', 'list'])
'[1, "simple", "list"]'
json.dump()
序列化对象为 文本文件。
>>> import json
>>> f = open('dump-test.json', 'w')
>>> json.dump([1, 'simple', 'list'], f)
>>> f.close()
>>> f = open('dump-test.json', 'r')
>>> for line in f:
... print(line, end='')
...
[1, "simple", "list"]>>>
json.load(f)
解码文件。
>>> f = open('dump-test.json', 'r')
>>> json.load(f)
[1, 'simple', 'list']
>>> f.close()