Python 3 文档(简体中文) 3.2.2 documentation

Version: 3.2.2

3. 非正式介绍Python

在以下的例子中, 输入和输出通过提示符 (>>>...) 来区分: 要运行示例, 你必须在提示符出现后键入提示符后面的所有内容; 不以提示符开头的行是解释器的输出.

注意, 在例子中有以一个次提示符独占一行时意味着你必须加入一个空行; 用来表示多行命令的结束.

这里有许多例子, 都是在交互式的提示符后中输入, 包括注释. Python 中的注释以一个井号, # 开头, 一直延伸到该物理行的最后. 注释既可以出现在一行的开头,也可以跟着空白或代码后面, 但不能在字符串里面. 在字符串里面的井号只是一个井号字符. 因为注释使用来使代码清晰的, 而不会被 Python 解释, 所以在键入例子是可以省略它们.

例如:

# 这是第一个注释
SPAM = 1                 # 这是第二个注释
                         # ... 而现在是第三个!
STRING = "# 这不是注释."

3.1. 把 Python 当计算器使用

让我们尝试一些简单的 Python 命令. 打开解释器, 等待主提示符, >>>, 出现. (这不会很久)

3.1.1. 数值

解释器可作为简单的计算器: 输入表达式给它, 它将输出表达式的值. 表达式语法很直白: 操作符 +, -, *, / 就像大多数语言一样工作 (例如, Pasal 和 C); 圆括号用以分组. 例如:

>>> 2+2
4
>>> # 这是注释
... 2+2
4
>>> 2+2  # 代码同一行的注释
4
>>> (50-5*6)/4
5.0
>>> 8/5 # 整数相除时并不会丢失小数部分
1.6

注意: 在你那儿,可能结果并不完全相同;因为不同机器上的浮点数结果可能不同 待会我们会讲如何控制浮点数输出地显示. 具体参见 浮点算术: 问题和限制 中关于浮点数的细节和表示法的完整讨论.

要从整数相除中得到一个整数, 丢弃任何小数部分, 可以使用另一个操作符, //:

>>> # 整数相除返回地板数:
... 7//3
2
>>> 7//-3
-3

等号 ('=') 用于把一个值分配给一个变量. 其后不会输出任何结果,而是下一个交互提示符:

>>> width = 20
>>> height = 5*9
>>> width * height
900

一个值可以同时被赋给多个变量:

>>> x = y = z = 0  # 给 x, y 和 z 赋值 0
>>> x
0
>>> y
0
>>> z
0

变量在使用之前必须要被 “定义” (分配一个值), 否则会产生一个错误:

>>> # 尝试访问未定义的变量
... n
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined

Python 完全支持浮点数; 在混合计算时,Pyhton 会把整型转换成为浮点数:

>>> 3 * 3.75 / 1.5
7.5
>>> 7.0 / 2
3.5

复数也有支持; 虚数部分写得时候要加上后缀, ji. 实部非零的复数被写作 (real+imagj), 也可以通过函式 complex(real, imag) 生成.

>>> 1j * 1J
(-1+0j)
>>> 1j * complex(0, 1)
(-1+0j)
>>> 3+1j*3
(3+3j)
>>> (3+1j)*3
(9+3j)
>>> (1+2j)/(1+1j)
(1.5+0.5j)

复数总是表达为两个浮点数, 实部和虚部. 要从复数 z 中抽取这些部分,使用 z.realz.imag

>>> a=1.5+0.5j
>>> a.real
1.5
>>> a.imag
0.5

浮点数和整数的转换函式 (float(), int()) 不能用于复数 — 没有正确的方法能把一个复数转换为一个实数. 使用 abs(z) 得到它的模 (以一个浮点数), 使用 z.real 得到他的实部:

>>> a=3.0+4.0j
>>> float(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: can't convert complex to float; use abs(z)
>>> a.real
3.0
>>> a.imag
4.0
>>> abs(a)  # sqrt(a.real**2 + a.imag**2)
5.0

在交互模式下, 最后一个表达式的值被分配给变量 _. 这意味着当你把 Python 用作桌面计算器时, 可以方便的进行连续计算, 例如:

>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_, 2)
113.06

我们应该将这这个变量视作只读的. 不要试图给它赋值 — 否则你会创建一个同名的局部变量, 而隐藏原本内置变量的魔术效果.

3.1.2. 字符串

除了数字, Python 也可以通过几种不同的方式来操作字符串. 字符串是用单引号或双引号包裹起来的:

>>> 'spam eggs'
'spam eggs'
>>> 'doesn\'t'
"doesn't"
>>> "doesn't"
"doesn't"
>>> '"Yes," he said.'
'"Yes," he said.'
>>> "\"Yes,\" he said."
'"Yes," he said.'
>>> '"Isn\'t," she said.'
'"Isn\'t," she said.'

解释器以字符串键入时相同的方式打印它们: 在引号里面, 使用引号或其它使用反斜杠的转义字符以说明精确的值. 当字符串包含单引号而没有双引号时, 就使用 双引号包围它, 否则, 使用单引号. print() 函数为如此的字符串提供了一个更可读的输出.

字符串有几种方法来跨越多行. 继续行可以被使用, 在一行最后加上一个反斜杠以表明下一行是这行的逻辑延续:

hello = "这是一个相当长的字符串包含\n\
几行文本, 就像你在 C 里做的一样.\n\
    注意开通的空白是\
 有意义的."

print(hello)

注意, 换行依旧需要在字符串里嵌入 \n – 在后面的反斜杠后面的换行被丢弃了. 该示例会打印如下内容:

这是一个相当长的字符串包含
几行文本, 就像你在 C 里做的一样.
    注意开通的空白是 有意义的.

另一种方法, 字符串可以使用一对匹配的三引号对包围: """'''. 当使用三引号时, 回车不需要被舍弃, 他们会包含在字符串里. 于是下面的例子使用了一个反斜杠来避免最初不想要的空行.

print("""\
用途: thingy [OPTIONS]
     -h                        显示用途信息
     -H hostname               连接到的主机名
""")

产生如下输入:

用途: thingy [OPTIONS]
     -h                        显示用途信息
     -H hostname               连接到的主机名

如果我们把字符串变为一个 “未处理” 字符串, \n 序列不会转义成回车, 但是行末的反斜杠, 以及源中的回车符, 都会当成数据包含在字符串里. 因此, 这个例子:

hello = r"这是一个相当长的字符串包含\n\
几行文本, 就像你在 C 里做的一样."

print(hello)

将会打印:

这是一个相当长的字符串包含\n\
几行文本, 就像你在 C 里做的一样.

字符串可以使用 + 操作符来连接 (粘在一起), 使用 * 操作符重复:

>>> word = 'Help' + 'A'
>>> word
'HelpA'
>>> '<' + word*5 + '>'
'<HelpAHelpAHelpAHelpAHelpA>'

两个靠着一起的字符串会自动的连接; 上面例子的第一行也可以写成 word = 'Help' 'A'; 这只能用于两个字符串常量, 而不能用于任意字符串表达式:

>>> 'str' 'ing'                   #  <-  可以
'string'
>>> 'str'.strip() + 'ing'   #  <-  可以
'string'
>>> 'str'.strip() 'ing'     #  <-  不正确
  File "<stdin>", line 1, in ?
    'str'.strip() 'ing'
                      ^
SyntaxError: invalid syntax

字符串可以使用下标 (索引); 就像 C 一样, 字符串的第一个字符的下标 (索引) 为 0. 没有独立的字符串类型; 一个字符串就是一个大小为一的字符串. 就像 Icon 程序语言一样, 子字符串可以通过*切片符号*指定: 冒号分隔的两个索引.

>>> word[4]
'A'
>>> word[0:2]
'He'
>>> word[2:4]
'lp'

切片索引有一些有用的默认值; 省略的第一个索引默认为零, 省略的第二个索引默认为字符串的大小.

>>> word[:2]    # 头两个字符
'He'
>>> word[2:]    # 除了头两个字符
'lpA'

与 C 字符串不一样, Python 字符串不可以改变. 给字符串的索引位置赋值会产生一个错误:

>>> word[0] = 'x'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: 'str' object does not support item assignment
>>> word[:1] = 'Splat'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: 'str' object does not support slice assignment

然而, 使用内容组合创建新字符串是简单和有效的:

>>> 'x' + word[1:]
'xelpA'
>>> 'Splat' + word[4]
'SplatA'

这有一个有用的切片操作的恒等式: s[:i] + s[i:] 等于 s.

>>> word[:2] + word[2:]
'HelpA'
>>> word[:3] + word[3:]
'HelpA'

退化的切片索引被处理地很优雅: 太大的索引会被字符串大小所代替, 上界比下界小就返回空字符串.

>>> word[1:100]
'elpA'
>>> word[10:]
''
>>> word[2:1]
''

索引可以是负数, 那样就会从右边开始算起. 例如:

>>> word[-1]     # 最后一个字符
'A'
>>> word[-2]     # 倒数第二个字符
'p'
>>> word[-2:]    # 最后两个字符
'pA'
>>> word[:-2]    # 除最后两个字符的其他字符
'Hel'

但是要注意, -0 与 0 是完全一样的, 因此它不会从右边开始数!

>>> word[-0]     # (因为 -0 等于 0)
'H'

越界的负切片索引会被截断, 当不要对单元素 (非切片) 索引使用越界索引.

>>> word[-100:]
'HelpA'
>>> word[-10]    # 错误
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
IndexError: string index out of range

记忆切片工作方式的一个方法是把索引看作是字符*之间*的点, 第一字符的左边记作 0. 包含 n 个字符的字符串最后一个字符的右边的索引就是 n, 例如:

 +---+---+---+---+---+
 | H | e | l | p | A |
 +---+---+---+---+---+
 0   1   2   3   4   5
-5  -4  -3  -2  -1

第一行给出了索引 0...5 在字符串里的位置; 第二行给出了相应的负索引. ij 的切片由标号为 ij 的边缘中间的字符所构成.

对于没有越界非负索引, 切片的长度就是两个索引之差. 例如, word[1:3] 的长度是 2.

内建函数 len() 返回字符串的长度:

>>> s = 'supercalifragilisticexpialidocious'
>>> len(s)
34

See also

Sequence Types — str, bytes, bytearray, list, tuple, range
字符串是*序列类型*的例子, 支持该类型的一般操作.
String Methods
字符串支持大量用与基本变换和搜索的方法.
String Formatting
在这描述了使用 str.format() 格式字符串的信息.
Old String Formatting Operations
当字符串和 Unicode 字符串为 % 操作符的左操作数时, 老的格式操作就会被调用, 在这里描述了更多细节.

3.1.3. 关于 Unicode

自 Python 3.0 开始, 所有字符串都支持 Unicode (参见 http://www.unicode.org/). Unicode 的益处在于它为自古至今所有文本中使用的每个字符提供了一个序号. 在以前, 只有 256 个序号表示文字字符. 一般地, 文本被一个映射序号到文本字符的编码页所限制. 尤其在软件的国际化 (internationalization, 通常被写作 i18n'i' + 18 个字符 + 'n') 时尤其混乱. Unicode 通过为所有文本定义一个编码页解决了这些难题.

如果你想在字符串里加入特殊字符, 可以使用 Unicode-Escape 编码. 下面的例子说明了如何做到这点:

>>> 'Hello\u0020World !'
'Hello World !'

转义序列 \u0020 表明在给出的位置, 使用序号值 0x0020 (空格字符), 插入这个 Unicode 字符.

其它字符通过直接地使用它们各自的序号值作为 Unicode 序号而被解释. 如果你有使用标准 Latin-1 编码, 在很多西方国家里使用, 的字符串, 你会方便地发现 Unicode 的前 256 个字符与 Latin-1 的一样.

除这些标准编码以外, Python 还提供了整套其它方法, 通过一个已知编码的基础来创建 Unicode 字符串.

字符串对象提供了一个 encode() 方法, 用于使用一个特殊编码转换字符串到字节序列, 该方法带有一个参数, 编码的名字. 优先选择编码的小写名字.

>>> "Äpfel".encode('utf-8')
b'\xc3\x84pfel'

3.1.4. 列表

Python 有一些*复合*数据类型, 用来把其它值分组. 最全能的就是 list, 它可以写为在方括号中的通过逗号分隔的一列值 (项). 列表的项并不需要是同一类型.

>>> a = ['spam', 'eggs', 100, 1234]
>>> a
['spam', 'eggs', 100, 1234]

就像字符串索引, 列表的索引从 0 开始, 列表也可以切片, 连接等等:

>>> a[0]
'spam'
>>> a[3]
1234
>>> a[-2]
100
>>> a[1:-1]
['eggs', 100]
>>> a[:2] + ['bacon', 2*2]
['spam', 'eggs', 'bacon', 4]
>>> 3*a[:3] + ['Boo!']
['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boo!']

所有的切片操作返回一个包含请求元素的新列表. 这意味着, 下面的的切片返回列表 a 的一个浅复制:

>>> a[:]
['spam', 'eggs', 100, 1234]

不像*不可变*的字符串, 改变列表中单个元素是可能的.

>>> a
['spam', 'eggs', 100, 1234]
>>> a[2] = a[2] + 23
>>> a
['spam', 'eggs', 123, 1234]

为切片赋值同样可能, 这甚至能改变字符串的大小, 或者完全的清除它:

>>> # 替代一些项:
... a[0:2] = [1, 12]
>>> a
[1, 12, 123, 1234]
>>> # 移除一些:
... a[0:2] = []
>>> a
[123, 1234]
>>> # 插入一些:
... a[1:1] = ['bletch', 'xyzzy']
>>> a
[123, 'bletch', 'xyzzy', 1234]
>>> # 在开始处插入自身 (的一个拷贝)
>>> a[:0] = a
>>> a
[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
>>> # 清除列表: 用空列表替代所有的项
>>> a[:] = []
>>> a
[]

内建函数 len() 同样对列表有效:

>>> a = ['a', 'b', 'c', 'd']
>>> len(a)
4

嵌套列表 (创建包含其它列表的列表) 是可能的, 例如:

>>> q = [2, 3]
>>> p = [1, q, 4]
>>> len(p)
3
>>> p[1]
[2, 3]
>>> p[1][0]
2

你可以在列表末尾加入一些东西:

>>> p[1].append('xtra')
>>> p
[1, [2, 3, 'xtra'], 4]
>>> q
[2, 3, 'xtra']

注意在最后的例子里, p[1]q 确实指向同一个对象! 我们在以后会回到*对象语义*.

3.2. 编程第一步

当然, 我们可以使用 Python 做比 2 + 2 更复杂的任务. 例如, 我们可以如下的写出 Fibonacci 序列的最初子序列:

>>> # Fibonacci 序列:
... # 两个元素的值定义下一个
... a, b = 0, 1
>>> while b < 10:
...     print(b)
...     a, b = b, a+b
...
1
1
2
3
5
8

这个例子介绍了几个新特性.

  • 第一行包括一次*多重赋值*: 变量 ab 同时地得到新值 0 和 1. 在最后一行又使用了一次, 演示了右边的表达式在任何赋值之前就已经被计算了. 右边表达式从左至右地计算.

  • 当条件 (在这里: b < 10) 保持为真时, while 循环会一直执行. 在 Python 中, 就像 C 里一样, 任何非零整数都为真; 零为假. 条件也可以是字符串或列表, 实际上可以是任意序列; 长度不为零时就为真, 空序列为假. 本例中使用的测试是一个简单的比较. 标准比较符与 C 中写得一样: < (小于), > (大于), == (等于), <= (小于或等于), >= (大于或等于) 和 != (不等于).

  • 循环*体*是*缩进*的: 缩进是 Python 分组语句的方法. Python 不 (到目前!) 提供智能输入行编辑功能, 因此, 你需要为每个缩进键入制表符或空格. 在练习中, 你会使用一个文本编辑器来为 Python 准备更复杂的输入; 大多文本编辑器带有自动缩进功能. 当一个复合语句交互地输入时, 必须跟上一个空行以表明语句结束 (因为语法分析器猜不到何时你键入了最后一行). 注意, 在同一基本块里的每一行必须以同一个数量缩进.

  • print() 函数写出给它的表达是的值. 它与就写出你想要写的表达式有所不同 (就像我们在之前计算器例子中一样), 它可以处理多个表达式, 浮点数, 和字符串. 打印字符串时没有引号, 在不同项之间插入了一个空格, 因此, 你可以把东西格式得漂亮, 就像这:

    >>> i = 256*256
    >>> print('The value of i is', i)
    The value of i is 65536
    

    关键词 end 可以用来避免输出后的回车, 或者以一个不同的字符串结束输出:

    >>> a, b = 0, 1
    >>> while b < 1000:
    ...     print(b, end=',')
    ...     a, b = b, a+b
    ...
    1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
    

See also

(^.^)