3. 输入与输出#

Python中格式化输出方法有:

3.1. 格式化字符串字面值#

格式化字符串字面值 (简称为 f-字符串)在字符串前加前缀 f 或 F,通过 {expression} 表达式,把 Python 表达式的值添加到字符串内。

格式说明符是可选的,写在表达式后面,可以更好地控制格式化值的方式。下例将 pi 舍入到小数点后三位:

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}.')
print(f'My hovercraft is full of {animals!r}.')
My hovercraft is full of eels.
My hovercraft is full of 'eels'.

= 说明符可被用于将一个表达式扩展为表达式文本、等号再加表达式求值结果的形式。

形式为 f’{expr=}’ 的 f-字符串将扩展表示为表达式文本,加一个等于号,再加表达式的求值结果

bugs = 'roaches'
count = 13
area = 'living room'
print(f'Debugging {bugs=} {count=} {area=}')
Debugging bugs='roaches' count=13 area='living room'

3.2. 字符串 format() 方法#

  • 花括号及之内的字符(称为格式字段)被替换为传递给 str.format() 方法的对象

  • 花括号中的数字表示传递给 str.format() 方法的对象所在的位置

  • 可以使用关键字参数名引用值

更多使用方法见 格式字符串语法

print('We are the {} who say "{}!"'.format('knights', 'Ni'))
print('{0} and {1}'.format('spam', 'eggs'))
print('{1} and {0}'.format('spam', 'eggs'))

print('This {food} is {adjective}.'.format(
      food='spam', adjective='absolutely horrible'))
We are the knights who say "Ni!"
spam and eggs
eggs and spam
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 字典作为采用 ** 标记的关键字参数传入:

table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
# 包含所有局部变量的字典
table = {k: str(v) for k, v in vars().items()}
message = " ".join([f'{k}: ' + '{' + k +'};' for k in table.keys()])
print(message.format(**table))
__name__: __main__; __doc__: Automatically created module for IPython interactive environment; __package__: None; __loader__: None; __spec__: None; __builtin__: <module 'builtins' (built-in)>; __builtins__: <module 'builtins' (built-in)>; _ih: ['', "import math\n\nprint(f'The value of pi is approximately {math.pi:.3f}.')", "table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}\n\nfor name, phone in table.items():\n    print(f'{name:10} ==> {phone:10d}')", "animals = 'eels'\nprint(f'My hovercraft is full of {animals}.')\nprint(f'My hovercraft is full of {animals!r}.')", "bugs = 'roaches'\ncount = 13\narea = 'living room'\nprint(f'Debugging {bugs=} {count=} {area=}')", 'print(\'We are the {} who say "{}!"\'.format(\'knights\', \'Ni\'))\nprint(\'{0} and {1}\'.format(\'spam\', \'eggs\'))\nprint(\'{1} and {0}\'.format(\'spam\', \'eggs\'))\n\nprint(\'This {food} is {adjective}.\'.format(\n      food=\'spam\', adjective=\'absolutely horrible\'))', "print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', other='Georg'))", "table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}\nprint('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))", '# 包含所有局部变量的字典\ntable = {k: str(v) for k, v in vars().items()}\nmessage = " ".join([f\'{k}: \' + \'{\' + k +\'};\' for k in table.keys()])\nprint(message.format(**table))']; _oh: {}; _dh: [PosixPath('/var/www/the-way-to-python')]; In: ['', "import math\n\nprint(f'The value of pi is approximately {math.pi:.3f}.')", "table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}\n\nfor name, phone in table.items():\n    print(f'{name:10} ==> {phone:10d}')", "animals = 'eels'\nprint(f'My hovercraft is full of {animals}.')\nprint(f'My hovercraft is full of {animals!r}.')", "bugs = 'roaches'\ncount = 13\narea = 'living room'\nprint(f'Debugging {bugs=} {count=} {area=}')", 'print(\'We are the {} who say "{}!"\'.format(\'knights\', \'Ni\'))\nprint(\'{0} and {1}\'.format(\'spam\', \'eggs\'))\nprint(\'{1} and {0}\'.format(\'spam\', \'eggs\'))\n\nprint(\'This {food} is {adjective}.\'.format(\n      food=\'spam\', adjective=\'absolutely horrible\'))', "print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', other='Georg'))", "table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}\nprint('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))", '# 包含所有局部变量的字典\ntable = {k: str(v) for k, v in vars().items()}\nmessage = " ".join([f\'{k}: \' + \'{\' + k +\'};\' for k in table.keys()])\nprint(message.format(**table))']; Out: {}; get_ipython: <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x7f071e3a50f0>>; exit: <IPython.core.autocall.ZMQExitAutocall object at 0x7f071e3a5a20>; quit: <IPython.core.autocall.ZMQExitAutocall object at 0x7f071e3a5a20>; open: <function open at 0x7f072fbee290>; _: ; __: ; ___: ; _i: table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table)); _ii: print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', other='Georg')); _iii: print('We are the {} who say "{}!"'.format('knights', 'Ni'))
print('{0} and {1}'.format('spam', 'eggs'))
print('{1} and {0}'.format('spam', 'eggs'))

print('This {food} is {adjective}.'.format(
      food='spam', adjective='absolutely horrible')); _i1: import math

print(f'The value of pi is approximately {math.pi:.3f}.'); math: <module 'math' (built-in)>; _i2: table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}

for name, phone in table.items():
    print(f'{name:10} ==> {phone:10d}'); table: {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}; name: Dcab; phone: 7678; _i3: animals = 'eels'
print(f'My hovercraft is full of {animals}.')
print(f'My hovercraft is full of {animals!r}.'); animals: eels; _i4: bugs = 'roaches'
count = 13
area = 'living room'
print(f'Debugging {bugs=} {count=} {area=}'); bugs: roaches; count: 13; area: living room; _i5: print('We are the {} who say "{}!"'.format('knights', 'Ni'))
print('{0} and {1}'.format('spam', 'eggs'))
print('{1} and {0}'.format('spam', 'eggs'))

print('This {food} is {adjective}.'.format(
      food='spam', adjective='absolutely horrible')); _i6: print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', other='Georg')); _i7: table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table)); _i8: # 包含所有局部变量的字典
table = {k: str(v) for k, v in vars().items()}
message = " ".join([f'{k}: ' + '{' + k +'};' for k in table.keys()])
print(message.format(**table));
# 打印给定的整数及其平方与立方

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

3.3. str() 与 repr()#

str() 函数返回供人阅读的值,repr() 则生成适于解释器读取的值(如果没有等效的语法,则强制执行 SyntaxError)。对于没有支持供人阅读展示结果的对象, str() 返回与 repr() 相同的值。一般情况下,数字、列表或字典等结构的值,使用这两个函数输出的表现形式是一样的。字符串有两种不同的表现形式。

s = 'Hello, world.'
str(s)
'Hello, world.'
repr(s)
"'Hello, world.'"
str(1/7)
'0.14285714285714285'
x = 10 * 3.25
y = 200 * 200
s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'
print(s)
The value of x is 32.5, and y is 40000...
hello = 'hello, world\n'
hellos = repr(hello)
print(hellos)
'hello, world\n'
repr((x, y, ('spam', 'eggs')))
"(32.5, 40000, ('spam', 'eggs'))"

3.4. 读写文件#

打开文件语法:

open(filename, mode, encoding=None)
  • filename是文件名字符串

  • mode是包含描述文件使用方式字符的字符串,省略时的默认值为 ‘r’

    • ‘r’ ,表示文件只能读取

    • ‘w’ 表示只能写入(现有同名文件会被覆盖)

    • ‘a’ 表示打开文件并追加内容,任何写入的数据会自动添加到文件末尾

    • ‘r+’ 表示打开文件进行读写

    • ‘b’ 可以用 binary mode 打开文件,二进制模式的数据是以 bytes 对象的形式读写的

  • encoding指定待打开文件的编码,如果没有指定 encoding ,默认的是与平台有关的。在二进制模式下打开文件时,你不能指定 encoding 。

在文本模式下读取文件时,默认把平台特定的行结束符(Unix 上为 \n, Windows 上为 \r\n)转换为 \n。在文本模式下写入数据时,默认把 \n 转换回平台特定结束符。这种操作方式在后台修改文件数据对文本文件来说没有问题,但会破坏 JPEG 或 EXE 等二进制文件中的数据。注意,在读写此类文件时,一定要使用二进制模式。

处理文件对象时,最好使用 with 关键字。优点是,子句体结束后,文件会正确关闭,即便触发异常也可以。而且,使用 with 相比等效的 try-finally 代码块要简短得多:

with open('workfile', encoding="utf-8") as f:
    read_data = f.read()

# 我们可以检测文件是否已被自动关闭。
f.closed
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Cell In[17], line 1
----> 1 with open('workfile', encoding="utf-8") as f:
      2     read_data = f.read()
      4 # 我们可以检测文件是否已被自动关闭。

File ~/myenv/lib/python3.10/site-packages/IPython/core/interactiveshell.py:324, in _modified_open(file, *args, **kwargs)
    317 if file in {0, 1, 2}:
    318     raise ValueError(
    319         f"IPython won't let you open fd={file} by default "
    320         "as it is likely to crash IPython. If you know what you are doing, "
    321         "you can use builtins' open."
    322     )
--> 324 return io_open(file, *args, **kwargs)

FileNotFoundError: [Errno 2] No such file or directory: 'workfile'

3.4.1. f.read(size)#

.read(size) 可用于读取文件内容,它会读取一些数据,并返回字符串str(文本模式),或字节串对象bytes(在二进制模式下)。 size 是可选的数值参数。省略 size 或 size 为负数时,读取并返回整个文件的内容。如已到达文件末尾,f.read() 返回空字符串(’’)。

3.4.2. f.readline()#

f.readline() 从文件中读取单行数据;字符串末尾保留换行符(\n),只有在文件不以换行符结尾时,文件的最后一行才会省略换行符。这种方式让返回值清晰明确;只要 f.readline() 返回空字符串,就表示已经到达了文件末尾,空行使用 ‘\n’ 表示,该字符串只包含一个换行符。

从文件中读取多行时,可以用循环遍历整个文件对象。这种操作能高效利用内存,快速,且代码简单:

for line in f:
    print(line, end='')