Python 官方简明教程 3:修订间差异
(没有差异)
|
2011年5月21日 (六) 08:27的版本
— 3. 非正式地介绍Python(已译完,尚未校对)
在随后的例子中,输入和输出被分别显示在时隐时现的提示符(>>> 和 ...)之后:为了实践这个例子,当提示符出现时,您必须在提示符后用键盘输入每一个字符;每一行不会由一个解释器输出的提示符起头。记住,在例子中独自占一行的提示符表示您必须键入一个空行;这是用于结束一个多行命令。
本手册中的一些例子,甚至在交互提示符后输入的内容中,包括了注释。Python中的注释由哈希字符 # 起头,一直延续到物理行尾。一个注释可以从行首开始显示,或者跟随在空格或代码之后,但不能位于文本串里面。一个文本串里的哈希字符就只是一个哈希字符。既然注释是用来阐述说明代码的,不会被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 # Zero x, y and z >>> x 0 >>> y 0 >>> z 0
在使用变量之前必须先“定义”变量(即赋予变量一个值),否则会有出错提示:
>>> # try to access an undefined variable ... 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,