blog/docs/code/python/io.md

303 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 输入输出
date: 2020-07-07 09:16:15
tags: [Python]
categories: [Python]
author: Anges黎梦
---
## 输入
### 键盘输入
```
str = input("请输入一个字符:")
print("你输入的内容是:", str)
```
使用这种方式就可以输入内容。
这种方式需要注意的就是输入内容的类型,以及接收到输入内容的后续处理。
## 输出
有几种方法可以显示程序的输出;数据可以以人类可读的形式打印出来,或者写入文件以供将来使用。
### 更漂亮的输出格式
到目前为止,我们遇到了两种写入值的方法:表达式语句 和 **print()** 函数。
(第三种是使用文件对象的 **write()** 方法;标准输出文件可以作为 sys.stdout 引用。)
通常,你需要更多地控制输出的格式,而不仅仅是打印空格分隔的值。有几种格式化输出的方法。
- 要使用 格式化字符串字面值 ,请在字符串的开始引号或三引号之前加上一个 f 或 F 。
在此字符串中,你可以在 { 和 } 字符之间写可以引用的变量或字面值的 Python 表达式。
```
>>>
>>> year = 2016
>>> event = 'Referendum'
>>> f'Results of the {year} {event}'
'Results of the 2016 Referendum'
```
- 字符串的 str.format() 方法需要更多的手动操作。你仍将使用 { 和 } 来标记变量将被替换的位置,并且可以提供详细的格式化指令,但你还需要提供要格式化的信息。
```
>>>
>>> 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%'
```
- 最后,你可以使用字符串切片和连接操作自己完成所有的字符串处理,以创建你可以想象的任何布局。字符串类型有一些方法可以执行将字符串填充到给定列宽的有用操作。
当你不需要花哨的输出而只是想快速显示某些变量以进行调试时,可以使用 repr() or str() 函数将任何值转化为字符串。
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...
>>> # The repr() of a string adds string quotes and backslashes:
... hello = 'hello, world\n'
>>> hellos = repr(hello)
>>> print(hellos)
'hello, world\n'
>>> # The argument to repr() may be any Python object:
... repr((x, y, ('spam', 'eggs')))
"(32.5, 40000, ('spam', 'eggs'))"
```
string 模块包含一个 Template 类,它提供了另一种将值替换为字符串的方法,使用类似 $x 的占位符并用字典中的值替换它们,但对格式的控制要少的多。
### 格式化字符串文字
格式化字符串字面值 (常简称为 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}.')
My hovercraft is full of eels.
>>> print(f'My hovercraft is full of {animals!r}.')
My hovercraft is full of 'eels'.
```
有关这些格式规范的参考,请参阅参考指南 格式规格迷你语言。
### 字符串的 format() 方法
str.format() 方法的基本用法如下所示:
```
>>>
>>> print('We are the {} who say "{}!"'.format('knights', 'Ni'))
We are the knights who say "Ni!"
```
花括号和其中的字符(称为格式字段)将替换为传递给 str.format() 方法的对象。花括号中的数字可用来表示传递给 str.format() 方法的对象的位置。
```
>>>
>>> print('{0} and {1}'.format('spam', 'eggs'))
spam and eggs
>>> print('{1} and {0}'.format('spam', 'eggs'))
eggs and spam
```
如果在 str.format() 方法中使用关键字参数,则使用参数的名称引用它们的值。:
```
>>>
>>> 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
```
这也可以通过使用 '**' 符号将 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
```
这在与内置函数 vars() 结合使用时非常有用,它会返回包含所有局部变量的字典。
例如,下面几行代码生成一组整齐的列,其中包含给定的整数和它的平方以及立方:
```
>>>
>>> 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
```
关于使用 str.format() 进行字符串格式化的完整概述,请参阅 格式字符串语法 。
### 手动格式化字符串
这是同一个平方和立方的表,手动格式化的:
```
>>>
>>> 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
```
(注意每列之间的一个空格是通过使用 print() 的方式添加的:它总是在其参数间添加空格。)
字符串对象的 str.rjust() 方法通过在左侧填充空格来对给定宽度的字段中的字符串进行右对齐。类似的方法还有 str.ljust() 和 str.center() 。这些方法不会写入任何东西,它们只是返回一个新的字符串,如果输入的字符串太长,它们不会截断字符串,而是原样返回;这虽然会弄乱你的列布局,但这通常比另一种方法好,后者会在显示值时可能不准确(如果你真的想截断,你可以添加一个切片操作,例如 x.ljust(n)[:n] 。)
还有另外一个方法str.zfill() ,它会在数字字符串的左边填充零。它能识别正负号:
```
>>>
>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'
```
### 旧的字符串格式化方法
% 运算符(求余)也可用于字符串格式化。 给定 'string' % values则 string 中的 % 实例会以零个或多个 values 元素替换。 此操作通常被称为字符串插值。 例如:
```
>>>
>>> import math
>>> print('The value of pi is approximately %5.3f.' % math.pi)
The value of pi is approximately 3.142.
```
字符串具有一种特殊的内置操作:使用 % (取模) 运算符。 这也被称为字符串的 格式化 或 插值 运算符。
转换标记符包含两个或更多字符并具有以下组成,且必须遵循此处规定的顺序:
- '%' 字符,用于标记转换符的起始。
- 映射键(可选),由加圆括号的字符序列组成 (例如 (somename))。
- 转换旗标(可选),用于影响某些转换类型的结果。
- 最小字段宽度(可选)。 如果指定为 '*' (星号),则实际宽度会从 values 元组的下一元素中读取,要转换的对象则为最小字段宽度和可选的精度之后的元素。
- 精度(可选),以在 '.' (点号) 之后加精度值的形式给出。 如果指定为 '*' (星号),则实际精度会从 values 元组的下一元素中读取,要转换的对象则为精度之后的元素。
- 长度修饰符(可选)。
- 转换类型。
当右边的参数为一个字典(或其他映射类型)时,字符串中的格式 必须 包含加圆括号的映射键,对应 '%' 字符之后字典中的每一项。 映射键将从映射中选取要格式化的值。 例如:
```
>>>
print('%(language)s has %(number)03d quote types.' %
{'language': "Python", "number": 2})
Python has 002 quote types.
```
在此情况下格式中不能出现 * 标记符(因其需要一个序列类的参数列表)。
转换旗标为:
Flag|含义
--:|---:
'#'|值的转换将使用“替代形式”(具体定义见下文)。
'0'|转换将为数字值填充零字符。
'-'|转换值将靠左对齐(如果同时给出 '0' 转换,则会覆盖后者)。
' '|(空格) 符号位转换产生的正数(或空字符串)前将留出一个空格。
'+'|符号字符 ('+' 或 '-') 将显示于转换结果的开头(会覆盖 "空格" 旗标)。
可以给出长度修饰符 (h, l 或 L),但会被忽略,因为对 Python 来说没有必要 -- 所以 %ld 等价于 %d。
转换类型为:
转换符|含义|注释
--:|:--:|---:
'd'|有符号十进制整数。|
'i'|有符号十进制整数。|
'o'|有符号八进制数。|(1)
'u'|过时类型 -- 等价于 'd'。|
'x'|有符号十六进制数(小写)。|(2)
'X'|有符号十六进制数(大写)。|(2)
'e'|浮点指数格式(小写)。|(3)
'E'|浮点指数格式(大写)。|(3)
'f'|浮点十进制格式。|(3)
'F'|浮点十进制格式。|(3)
'g'|浮点格式。 如果指数小于 -4 或不小于精度则使用小写指数格式,否则使用十进制格式。|(4)
'G'|浮点格式。 如果指数小于 -4 或不小于精度则使用大写指数格式,否则使用十进制格式。|(4)
'c'|单个字符(接受整数或单个字符的字符串)。|
'r'|字符串(使用 repr() 转换任何 Python 对象)。|(5)
's'|字符串(使用 str() 转换任何 Python 对象)。|(5)
'a'|字符串(使用 ascii() 转换任何 Python 对象)。|(5)
'%'|不转换参数,在结果中输出一个 '%' 字符。|
注释:
- 此替代形式会在第一个数码之前插入标示八进制数的前缀 ('0o')。
- 此替代形式会在第一个数码之前插入 '0x' 或 '0X' 前缀(取决于是使用 'x' 还是 'X' 格式)。
- 此替代形式总是会在结果中包含一个小数点,即使其后并没有数码。
- 小数点后的数码位数由精度决定,默认为 6。
- 此替代形式总是会在结果中包含一个小数点,末尾各位的零不会如其他情况下那样被移除。
- 小数点前后的有效数码位数由精度决定,默认为 6。
- 如果精度为 N输出将截短为 N 个字符。