Python 官方简明教程 3

来自Ubuntu中文
跳到导航跳到搜索

— 3. 非正式地介绍Python(已译完,未校对完)

在随后的例子中,输入前有提示符(>>> 和 ...),而输出前没有:要实践例子,当有提示符时,您必须输入在提示符后所有字符;不由提示符开头的行是解释器的输出。记住,在例子中独自占一行的次要提示符表示您必须键入一个空行;这用于结束一个多行命令。

本手册中的许多例子,甚至在交互提示符后输入的,都包括了注释。Python中的注释由井号 # (the hash character)开始,直到物理行的末尾。注释可以从行首开始,或者跟在空白或代码之后,但不位于字面字符串里面。字面字符串里的井号就只是井号。既然注释是用来阐明代码的,不会被Python解释,所以您可以在实践操作中省略键入例子中的注释。

例如:

# 这是第一行注释
SPAM = 1                 # 这是第二行注释
                         # ……第三行了!
STRING = "# 这不是注释。"

— 3.1. 把Python作为一个计算器

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

— 3.1.1. 数字

解释器可以作为一个简单计算器:您可以在解释器里键入一个表达式,它将输出表达式的值。表达式的语法很直白: +, -, * 和 / 和在许多其它语言(如Pascal或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
>>> x
0
>>> y
0
>>> z
0

变量在使用前必须先“定义”变量(即赋予变量一个值),否则会出现一个错误:

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

浮点数得到完全的支持;不同类型的数混合运算时会把整数转换为浮点数:

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

也支持复数;虚数带有 j 或 J 后缀。带有非零实部的复数记为 (实部+虚部j),或者使用 complex(实部, 虚部) 函数来创建。

>>> 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.real 和 z.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 = "This is a rather long string containing\n\
several lines of text just as you would do in C.\n\
    Note that whitespace at the beginning of the line is\
 significant."

print(hello)

注意,要换新的一行输出仍然需要嵌入字符 \n ——如果新的一行直接跟着反斜杠则不会换到新的一行输出。这个例子将会输出如下:

This is a rather long string containing
several lines of text just as you would do in C.
    Note that whitespace at the beginning of the line is significant.

或者,字符串可以被三个双引号 """ 或者三个单引号封装。使用三引号时,行的末端不必再添加转义符反斜杠,但这些行仍将被包括在同一个字符串内。因此以下的例子使用了一个义符反斜杠,防止在输出刚开始时产生一个不需要的空行。

print("""\
Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to
""")

随后产生的输出如下:

Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to

如果我们在一个“raw”后使用字符串,那么 \n 不会被转换成新的一行输出,但是行尾末端的的反斜杠,以及新的一行的源代码,都将作为整体数据包括在这个字符串内。例如这样:

hello = r"This is a rather long string containing\n\
several lines of text much as you would do in C."

print(hello)

将会输出:

This is a rather long string containing\n\
several lines of text much as you would do in 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]    # The first two characters
'He'
>>> word[2:]    # Everything except the first two characters
'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]     # The last character
'A'
>>> word[-2]     # The last-but-one character
'p'
>>> word[-2:]    # The last two characters
'pA'
>>> word[:-2]    # Everything except the last two characters
'Hel'

但注意, -0 就真的等于 0,所以 -0 不会从右开始计数!

>>> word[-0]     # (since -0 equals 0)
'H'

超出范围的负数索引会被截去多余部分,但不要在一个单索引(不是分切索引)里尝试使用:

>>> word[-100:]
'HelpA'
>>> word[-10]    # error
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 给出了字符串中索引的位置;第二行给出了相应的负数索引。分切部分从 i 到 j 分别由在边缘被标记为 i 和 j 的全部字符组成。

对于非负数分切部分,如果索引都在有效范围内,分切部分的长度就是索引的差值。例如, word[1:3] 的长度是2。

内置的函数 len() 用于返回一个字符串的长度:

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

请参考

序列类型——字符串,字节,字节数组,列表,元组,范围  字符串是序列类型的一个例子,也支持以下类型的通用操作。 字符串模式  字符串支持大量的模式用于基础转换和搜索。 字符串格式化  关于字符串格式化的信息请参考函数 str.format() 的表述。 旧的字符串格式化操作  当字符串和Unicode字符串是%运算符左边的操作数时,请参考旧的格式化操作调用方法。

— 3.1.3. 关于Unicode

Python从3.0版开始全面支持 Unicode (请参考 http://www.unicode.org/ )。

Unicode有个优点,它提供了在每个脚本里使用到的现在的和古老的每一个字符的次序列表。最早时,只有256个可用的脚本字符次序。文本通常绑定到一个被映射到脚本字符次序的代码页中。这样很容易产生混淆,尤其在国际化的软件方面更是如此(通常书写为 i18n —— 'i' + 18 个字符 + 'n')。Unicode通过为全部脚本定义一个代码页来解决这些问题。

如果您打算在脚本中包含特殊字符,您可以使用 Python Unicode-转义编码。如下例所示:

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

转义次序 \u0020 用来标志在指定的位置插入次序值是 0x0020 的Unicode字符(空格符)。

其它的字符由它们各自的次序值直接解释,就像Unicode次序一样。如果您有许多西方国家常用的标准拉丁-1编码文本串,你将能很方便地发现,较低次序的256个Unicode字符与Latin-1的256个字符一模一样。

除了这些标准编码,Python还提供了一整套方法用于在已知编码的基础上创建Unicode字符串。

可以使用一个专为字符串对像提供的 encode() 函数,把一个字符串转换为使用特定编码的次序字节,以编码的名称作为参数。首选小写的编码名称。

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

— 3.1.4. 列表

Python囊括了大量的复合数据类型,用于组织其它数值。最有用的是列表,即是写在方括号之间、用逗号分隔开的数值列表。列表内的项目不必全是相同的类型。

>>> 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]

也可以给分切部分赋值,甚至可以改变列表的尺寸或者完全清空列表:

>>> # Replace some items:
... a[0:2] = [1, 12]
>>> a
[1, 12, 123, 1234]
>>> # Remove some:
... a[0:2] = []
>>> a
[123, 1234]
>>> # Insert some:
... a[1:1] = ['bletch', 'xyzzy']
>>> a
[123, 'bletch', 'xyzzy', 1234]
>>> # Insert (a copy of) itself at the beginning
>>> a[:0] = a
>>> a
[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
>>> # Clear the list: replace all items with an empty list
>>> 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 series:
... # the sum of two elements defines the next
... a, b = 0, 1
>>> while b < 10:
...     print(b)
...     a, b = b, a+b
...
1
1
2
3
5
8

这个例子介绍了几个新特征。

  • 第一行包含了一个复合赋值:变量 a 和 b 同时得到新的值 0 和 1。在最后一行再次使用了同样的方法,可以看到,右边的表达式会在发生赋值变动之前已经执行。右边表达式的执行顺序是从左往右的。
  • 整个循环执行的时间取决于限定的条件是否为真(这里是: b < 10 )。在 Python 里,就像在C语言里一样,任何非零整数的值为真;零为假。限定条件可以是一个字符串或是一个列表的值,事实上可以是任何序列;任何非零长度的值都是真,空序列是假。在例子中实验的是一个简单的比较。标准的比较操作写法和C语言一样: < (小于), > (大于), == (等于), <= (小于等于), >= (大于等于)和 != (不等于)。
  • 书写循环体时是缩进的:缩进是Python分组说明的主要途径。Python(暂)不提供一个智能输入行的编辑功能,因此您必须为每一个缩进行键入一个制表符或空格符。在实践中您将会乐于使用一个文本编辑器,为更复杂的Python程序编写作准备;许多文本编辑器有自动缩进功能。当使用解释器交互输入一个复合语句时,循环体必须紧接着一个空行表示循环结束(因为解释器无法猜测出您什么时候才算是输入最后一行)。注意,每一个程序区段内的每一行都必须有相同的缩进量。
  • print() 函数输出表达式被赋予的值。它在处理复合表达式、浮点数和字符串方面,不同于仅仅输出的您想写出的表达式(就像我们较早前计算器的例子)。字符串的输出没有引号,空格被插入到项目之间,所以您可以很好地格式化输出,就像这样:
>>> i = 256*256
>>> print('The value of i is', i)
The value of i is 65536

关键字的末尾可以被用于防止输出新的一行,或者在输出的末尾添加不同的字符:

>>> 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,
————— 返回《 Python 官方简明教程 》目录 —————
—— 返回《 Python 手册 》总目录 ——