数据结构(Python语言描述)(第2版)
上QQ阅读APP看书,第一时间看更新

1.1 基本程序要素

和所有现代编程语言一样,Python也有大量的功能和结构,但它是少数几种基本程序要素相当简单的语言之一。本节将介绍使用Python编程的一些基础知识。

Python程序包含一个或多个模块。模块是指包含Python源代码的文件,其中可以包含语句、函数的定义以及类的定义。简短的Python程序也称为脚本(script),通常包含在一个模块之中;较长的或较为复杂的程序,通常包含一个主模块以及一个或多个支持模块。主模块会包含程序执行的起点,支持模块则会包含函数和类的定义。

我们来看一个完整的Python程序。这是一个和用户玩猜数字游戏的程序。一开始,计算机要求用户输入给定数值范围内所猜数字的最小值和最大值。随后,计算机“思考”出在这个范围之内的一个随机数,并反复要求用户猜测这个数,直到用户猜对为止。用户每次猜测之后,计算机都会给出一个提示,并且会在游戏结束时显示总的猜测次数。这个程序会用到本章稍后部分里将讨论的几种Python语句,例如输入语句、输出语句、赋值语句、循环语句和条件语句。这个程序还包含了一个函数的定义。

这个程序的代码如下(代码位于文件numberguess.py之中)。

"""
Author: Ken Lambert
Plays a game of guess the number with the user.
"""

import random

def main():
    """Inputs the bounds of the range of numbers
    and lets the user guess the computer’s number until
    the guess is correct."""
    smaller = int(input("Enter the smaller number: "))
    larger = int(input("Enter the larger number: "))
    myNumber = random.randint(smaller, larger)
    count = 0
    while True:
        count += 1
        userNumber = int(input("Enter your guess: "))
        if userNumber < myNumber:
            print("Too small")
        elif userNumber > myNumber:
            print("Too large")
        else:
            print("You’ve got it in", count, "tries!")
            break

if __name__ == "__main__":
    main()

用户和程序进行某次互动之后的输出如下。

Enter the smaller number: 1
Enter the larger number: 32
Enter your guess: 16
Too small
Enter your guess: 24
Too large
Enter your guess: 20
You’ve got it in 3 tries!

实际运行过程中,代码及其输出会显示为黑色、蓝色、橙色和绿色等不同的颜色。Python的IDLE会对代码加以着色,以便让程序员更方便地识别程序元素的各种类型。不同颜色的表示规则详见后续说明。

对于书里的大多数示例,你都可以通过在终端窗口中输入命令来运行它们的Python程序。例如,要运行文件numberguess.py里包含的程序,只需在大多数终端窗口中输入如下命令:

python3 numberguess.py

你可以通过Python的IDLE(Integrated DeveLopment Environment)创建或编辑一个Python模块。要启动IDLE,只需在终端提示符下输入idle或idle3命令,抑或通过快捷方式启动它。你也可以通过双击Python源代码文件(任何扩展名为.py的文件)或者右击源代码文件并在弹出的菜单中选择“通过IDLE打开或编辑”来启动IDLE。若要通过双击文件的方式启动IDLE,则需要确保源代码文件在系统里默认的打开方式已被设置为通过IDLE打开(macOS上这是默认设置,但在Windows上不是默认设置)。

IDLE提供了一个Shell窗口,可以交互式地运行Python表达式和语句。通过IDLE,你可以在编辑器窗口和Shell窗口之间来回切换,以开发和运行完整的程序。IDLE还能格式化代码,并对代码进行着色处理。

当你用IDLE打开Python文件时,文件就会显示在编辑器窗口里,这时Shell窗口会作为单独的窗口弹出。要运行文件里的程序,你只需把光标移动到编辑器窗口中,然后按下F5键。Python会在编辑器窗口中编译代码,然后在Shell窗口中运行它。

如果遇到Python程序没有响应或者无法正常退出的情况,可以按Ctrl+C组合键或者关闭Shell窗口来终止程序运行。

程序注释是指那些会被Python编译器忽略的文本,但对于阅读程序的人来说是非常有价值的。Python中的单行注释以#符号开头,并且直到当前行的末尾结束。在IDLE里,注释会显示为红色(本书为黑白印刷,故无法显示)。注释的示例如下:

#This is an end-of-line comment.

多行注释是用3个单引号或3个双引号括起来的一个字符串。这样的注释又称为文档字符串(docstring),用于对程序的主要结构进行文档化描述。前面给出的numberguess程序就包含了两个文档字符串:第一个文档字符串位于程序文件的顶部,用于描述整个numberguess模块;第二个文档字符串位于主函数(main)之下,用于描述这个函数做什么事情。尽管文档字符串看上去很简短,但是它们能在Python的Shell窗口中为程序员提供至关重要的帮助。

语言中的词法元素是用于构造语句的一类单词和符号。和所有高级编程语言一样,Python的一些基本符号也是关键字,例如if、while以及def。这些关键字在IDLE里会显示为橙色。词法元素还包括标识符(名称),字面值(数字、字符串和其他内置的数据结构),以及运算符和分隔符(引号、逗号、圆括号、方括号和大括号)。内置的函数名称的标识符会显示为紫色。

Python的关键字和名称是区分大小写的。也就是说,while是Python的关键字,而While则是程序员定义的名称。Python的关键字均以小写字母的方式拼写,并且在IDLE窗口中显示为橙色。

Python内置的函数名称均显示为黑色,但将其作为函数、类或方法名引用时显示为蓝色。名称可以以字母或下划线(_)开头,其后可以接任意数量的字母、下划线或数字。

在本书中,模块、变量、函数和方法的名称都是以小写字母的形式拼写的。除了模块,当这些名称包含多个单词时,那些位于后面的单词的首字母以大写形式拼写。类名遵循相同的惯例,但其首字母都是大写的。另外,如果一个变量名是常量,那么所有字母将大写,并且通过下划线来分隔单词。表1-1给出了Python命名惯例的一些示例。

表1-1 Python命名惯例的一些示例

要尽可能使用能够描述其在程序中所对应角色的名称。通常,变量名应该是名词或形容词(如果它们表示布尔值),而函数和方法名应该是动词(如果它们表示动作)、名词或形容词(如果它们表示返回的值)。

一种语言里的语法元素是由词法元素所组成的语句(表达式、语句、定义以及其他结构)的类型。和大多数高级语言不同,Python用空白符(white space character)(空格、制表符或换行符)来表示不同类型的语句的语法。这就是说,缩进和换行符在Python代码中是非常重要的。IDLE这样的智能编辑器有助于实现代码的正确缩进,这让程序员不需要操心用分号隔开句子,或者用花括号来标记语句块。本书的Python代码均以4个空格作为缩进宽度。

数字(整数或浮点数)的写法和其他编程语言里的一样。布尔值True和False是关键字。其他诸如字符串、元组、列表和字典这样的数据结构,也有与之相对应的字面值,参见后续内容。

字符串字面值

你可以用单引号、双引号或者成对的3个双引号或3个单引号将字符串括起来。最后的这种表示方法对于包含多行文本的字符串来说是很有用的。字符值是指只包含一个字符的字符串。\字符用于将非图形化的字符(例如,换行符\n和制表符\t,或者\字符本身)进行转义。下面的代码段及其输出展示了各种可能性。

print("Using double quotes")
print('Using single quotes')
print("Mentioning the word ‘Python’ by quoting it")
print("Embedding a\nline break with \\n")
print("""Embedding a
line break with triple quotes""")

输出结果如下。

Using double quotes 
Using single quotes 
Mentioning the word 'Python' by quoting it 
Embedding a 
line break with \n 
Embedding a 
line break with triple quotes

Python里的算术表达式用的是标准运算符(+、–、*、/、%)和中缀表示法。无论操作数是什么数字类型,/运算符都会生成一个浮点数,而//运算符会输出整数形式的商。当这些运算符和多项集[1](如字符串和列表)一起使用时,+运算符用于连接操作。此外,**运算符用于幂运算。

比较运算符有<、<=、>、>=、==以及!=,用于比较数字或字符串。

==运算符用于比较数据结构里的内容,例如,可以对两个列表进行比较;而is运算符则用于比较两个对象的标识是否一致。比较运算符会返回True或False。

逻辑运算符and、or和not会把0、None、空字符串以及空列表这样的值视为False,而把大多数其他Python值视为True。

下标运算符[]会和多项集对象一起使用,这是我们稍后会介绍的。

选择器运算符.用于引用一个模块、类或对象中一个具名的项。

Python运算符的优先级和其他语言是一样的(依次是选择运算符、函数调用运算符、下标运算符、算术运算符、比较运算符、逻辑运算符和赋值运算符)。括号也和其他语言一样,用于让子表达式更早地予以执行。

**和=运算符满足右向结合律,而其他运算符满足左向结合律。

调用函数的方法和其他语言中的也是一样的,即函数名称后面跟着用括号括起来的参数列表。示例如下:

min(5, 2)     # Returns 2

Python提供了一些标准函数,例如abs和round。你也可以从模块里导入其他函数。

标准输出函数print会将其参数显示到控制台。这个函数支持使用可变数量的参数。Python会自动为每个参数运行str函数,以获取其字符串表示,并且在输出之前用空格把每个字符串隔开。默认情况下,print会以换行符作为结束。

标准输入函数input会一直等待用户通过键盘输入文本。当用户按下回车键时,这个函数将返回一个包含所有输入字符的字符串。这个函数接受一个可选的字符串作为其参数,并且会不换行地打印出这个字符串,以提示用户进行输入。

你可以把一些数据类型名称当作类型转换函数使用。例如,当用户在键盘上输入一个数字时,input函数返回这个数字的字符串形式,而不是这个数字本身。程序必须先把这个字符串转换为int类型或float类型,然后才能进行数字处理。下面这段代码先要求用户输入圆的半径,然后把这个字符串转换为float类型,最后计算并输出圆的面积。

radius = float(input("Radius: "))
print("The area is", 3.14 * radius ** 2)

和大多数其他编程语言一样,Python允许算术表达式中的操作数具有不同的数值类型。在这种情况下,返回的结果类型会和操作数里最通用的类型相同。例如,把int类型的操作数和float类型的操作数相加,会得到float类型的数。

函数支持可选参数,因此在调用函数时,可以使用关键字对参数进行命名。例如,print函数默认在其要显示的参数后输出换行符。为了不产生新行,你可以把可选参数end赋值为一个空字符串,如下所示。

print("The cursor will stay on this line, at the end", end = "")

必选参数是没有默认值的;可选参数有默认值,并且在通过关键字使用它们时,只要它们处于必选参数之后,就可以按照任何顺序进行传递。

例如,标准函数round预期会有一个必选参数——这个参数是一个需要被四舍五入的数字;除此之外,还可以用第二个可选参数来对精度进行确认。当省略第二个参数时,这个函数会返回最接近的整数(int类型);而当包含第二个参数时,这个函数会返回一个浮点数(float类型)。示例如下。

>>> round(3.15)
3
>>> round(3.15, 1)
3.2

通常,在调用函数时,传递给它的参数数量必须至少和必选参数的数量相同。

注意:标准函数和Python的库函数在调用时都会对传入的参数进行类型检查。由程序员定义的函数则可以接收任何类型的参数,包括函数和类型本身。

Python中的变量是通过赋值语句引入的,例如:

PI = 3.1416

上述代码把变量PI的值设为3.1416。简单赋值语句的语法如下:

<identifier> = <expression>

也可以像下面这样,在一个赋值语句里,同时引入多个变量:

minValue, maxValue = 1, 100

因此,如果要交换变量a和b的值,就可以这样写:

a, b = b, a

赋值语句必须写在一行代码里,但是可以在逗号、圆括号、花括号或方括号之后换行。在没有这些分隔符号的情况下,还有一种实现语句换行的方法:用一个转义符\结束这一行代码。一般来说,采用这种方法时,这个符号会被放在表达式里的运算符之前或之后。如下示例在实际编写时并不需要换行:

minValue = min(100,
               200)
product = max(100, 200) \
          * 30

当你在逗号或转义符之后按回车键时,IDLE会自动缩进下一行代码。

在Python里,变量都可以被指定为任何类型的值。这些变量并不是像其他语言那样被声明为特定的类型,而只是被赋了一个值。

因此,在Python程序里,几乎永远都不会出现数据类型的名称。但是,值和对象都是有类型的,这些类型在表达式里作为操作数进行运算时,会在运行时进行类型检查,因此类型错误还是会被发现的。只是相对来说,程序员在编写代码时不用对数据类型进行太多的关注。

import语句使得另一个模块中的标识符可以被一个程序所见到。这些标识符可能是对象名、函数名或类名。有几种方式可以表示一条import语句。最简单的方式是,导入一个模块名称,例如:

import math

这使得在math模块中定义的任何名称,在当前的模块中都可以通过math.<name>形式的语法而变得可用。因此,math.sqrt(2)将返回2的平方根。

另一种导入的形式是,直接使用名称进入导入,这样一来,就可以不带模块名作为前缀而直接使用该名称了:

from math import sqrt
print(sqrt(2))

还可以通过列出几个单独的名称来导入它们:

from math import pi, sqrt
print(sqrt(2) * pi)

也可以使用*运算符导入一个模块中的所有名称,但是我们并不认为这是好的做法。

尽管Python的官方网站给出了关于Python语言的完整文档,但是在Python 的Shell窗口中也可以快速获取和语言大部分组成相关的帮助信息。要访问这样的帮助信息,只需在Shell提示符中输入名为help(<component>)的函数,其中的<component>是模块、数据类型、函数或方法的名称。例如,调用help(abs)和(math.sqrt)分别会显示abs和math.sqrt函数的文档。调用help(int)和help(math)将分别显示int类型和math模块中所有操作的文档。

注意,如果一个模块并非在Shell窗口启动时Python将要加载的内置模块,程序员必须先导入模块,然后才能查找相关的帮助信息。例如,Shell窗口中的如下会话将显示本章前面所介绍的numberguess程序的文档:

>>> import numberguess
>>> help(numberguess)
Help on module numberguess: 

NAME
    numberguess 

DESCRIPTION 
    Author: Ken Lambert 
    Plays a game of guess the number with the user. 

FUNCTIONS 
    main() 
        Inputs the bounds of the range of numbers, 
        and lets the user guess the computer’s number until
        the guess is correct. 

FILE
    /Users/ken/Documents/CS2Python/Chapters/Chapter1/numberguess.py