2.7 Python基础
Python是一种面向对象的解释型程序设计语言,在1989年由Guido van Rossum在荷兰国家数学和计算机科学研究所设计,并于1991年公开发行。
Python的源代码和解释器CPython全部遵循GPL(General Public License,通用公共许可)协议。任何人均可到Python的官方网站[39],以源代码或二进制形式下载Python解释器及其标准扩展库,也可以自由分发。该网站还提供了大量的第三方Python模块、程序、工具及附加文档。
Python语言结构简单,容易学习。Python包含丰富的跨平台标准库,可以方便地在UNIX、Windows和Mac操作系统之间切换。作为一种粘合剂语言,Python可以方便地粘合其他语言编写的代码,如C、C++和FORTRAN编写的程序。虽然Python语言功能强大,操作简洁,但本节主要讲解Python语言的网络数据抓取功能,即如何使用简单的Python语言编写代码,快速而准确地抓取网页上的内容。
虽然可以使用工具从网站上收集数据,但很多个性化数据的获取依旧需要使用编程来实现。考虑到易用性,Python才是数据获取的最佳选择[40](见图2.48)。
图2.48 编程语言排行
2.7.1 环境配置
Mac操作系统自带的Python不需配置即可使用,允许多个版本同时存在。图2.49显示系统中包含Python2.7.10和Python3.7.0两个版本。
图2.49 Mac系统安装的两个Python版本
Windows系统下,Python的安装非常简单。双击下载的安装包,出现Python安装向导,见图2.50,建议勾选界面底部的“Install launcher for all users (recommended)”和“Add Python3.5to PATH”选项,选择“Install Now”,然后单击“下一步”按钮,即可完成安装。
图2.50 Python安装向导
说明:
① 如果希望修改安装位置,可以选择“Customize installation”自定义安装模式。
② 如果没有勾选“Add Python3.5to PATH”选项,需要设置环境变量,设置方法如下。
右击“计算机”,在出现的快捷菜单中选择“属性|高级系统设置”,在“高级”选项卡中选择“环境变量”,在弹出的对话框的“系统变量”中选择“Path”,见图2.51,然后单击“编辑”按钮;在弹出的“编辑系统变量”对话框的“变量值”中添加Python的安装路径,见图2.52。如Python的安装路径是“C:\python”,则添加“;C:\python”(不区分大小写),前面的“;”是为了分隔多个安装路径。
安装结束后,可以在“cmd命令行”中输入“python”,如果出现图2.53所示的Python版本的数据,则表明安装正确。
另外,退出Python的函数是“exit( )”。
也可以选择“开始”菜单的“Python3.5|IDLE(Python3.564-bit)”,出现图2.54所示的信息,表明安装正确。
图2.51 设置Python环境变量
图2.52 编辑系统变量
图2.53 命令行显示Python版本的数据
图2.54 Python交互窗口
2.7.2 第一个Python程序
我们用2.7.1节介绍的第二种方法进入Python交互窗口,完成第一个Python程序。先尝试Python的使用方法,使用“print("hello world")”函数实现输出,见图2.55。
图2.55 第一次使用Python
然后新建第一个Python程序,并运行该程序,见图2.56,具体步骤如下。
<1> 选择“File|New File”菜单命令,新建程序文件。然后输入如下代码,注意英文大小写。
<2> 选择“File|Save”菜单命令,保存文件为“1.py”。
<3> 选择“Run|Run Module”菜单命令或按F5键运行程序,结果见图2.56。
图2.56 程序“1.py”运行结果
说明:
① 函数print( )是Python的一个重要输出函数,功能是将括号中的一个或多个对象输出。本例中将字符串“hello world”直接输出。实际上,该函数还可以输出数值、布尔、列表和字典等对象。
② Python语言严格区分大小写,使用函数时注意括号和双引号均为英文格式。
2.7.3 变量和运算符
变量是在程序运行过程中值允许改变的量。变量存储在计算机的内存中,Python变量不需要声明,变量被赋值后就意味着创建了变量,即根据赋值的数据类型在内存中开辟一块空间保存变量的值,因此变量可以是整数,也可以是小数,还可以是字符等,在后续章节中有更详细的介绍和使用。常见的变量使用方法如下。
第1条语句为变量var1赋值为整数1,第2条语句为变量var2赋值为小数“3.14”,第3条语句为变量var3赋值为字符串"abc"。
用“=”为变量赋值,左侧是变量名,右侧是变量值。Python也允许同时为多个变量赋相同或不同的值,格式如下。
变量名是标识符的一种,必须严格遵守Python标识符的规定。变量名的首字符必须是字母或下划线,其他字符可以包含字母、数字和下划线。注意,变量名不可以是Python保留的关键字。查看Python关键字的方法是进入帮助功能,然后输入“keywords”,具体方法如下。
注意:help( )函数的功能是查看函数或模块用途的详细说明,按q键退出帮助。
Python的关键字有25个,见图2.57。
图2.57 Python的关键字
变量被赋值后,可以使用type( )函数查看变量中保存值(或者说对象)的数据类型,使用id( )函数查看其分配的内存空间,具体方法如下。
说明:
① 变量var1保存的对象是整数数据(int),变量var2保存的对象是浮点(也称为小数)型数据(float),这两种数据统称为数值型数据。变量var3保存的对象是字符串(str)。
② 对象是有数据类型的,但变量无数据类型。如上例中的小数“3.14”是浮点型数据类型的对象,被赋予变量var2,变量可以被多次赋值,每次赋值的对象的数据类型可以是不同的。例如:
Python有6种数据类型,分别是Number(数字)、String(字符串)、List(列表)、Tuple(元组)、Sets(集合)、Dictionary(字典)。本节主要介绍前3种数据类型。
1.Number(数字,也称为数值)型数据
Python支持4种数值型数据,除了前面使用的int和float,还有bool(布尔)和complex(复数)。
布尔型数据仅包含“True”和“False”两个值,对应的数字分别是“1”和“0”,它们可以与数字相加,任意布尔型数据也可以相加。例如:
复数型数据由实数和虚数构成,如“a + bj”,或者用函数complex(a,b)表示。例如:
2.String(字符串)型数据
字符串是由单引号(')或双引号(")括起来的零个或多个字符。字符串的索引以“0”为初始值,索引“-1”为右侧末尾的位置。如2.7.2节中第一个Python程序中的字符串"hello world",字符串的索引值可以方便地将字符串中的部分字符取出,例如:
说明:
① “[0]”表示字符串的第1个字符,“[-1]”表示字符串的最后一个字符。
② “[3:]”表示字符串的第4个至最后一个字符。
③ “var8*2”表示复制当前字符串,数字表示复制的次数。
④ "UCASS" + var8表示将两个字符串连接。
⑤ “[6:9]”表示字符串的第7~9个字符。
字符串使用“+”运算符时,必须保证左右两侧均是字符串,若数据类型不正确,可能导致出错。例如:
说明:
① 表达式“100+ var8”中,“+”运算符左侧不是字符串,运算后产生了错误。
② 可以使用str(100)函数将数字100变成字符串"100",即可避免这类问题。
字符串中的“\”是转义特殊字符,具有特殊的含义。如“\n”表示换行,如不希望“\”转义,可以在字符串前面添加字符“r”,常见的转义特殊字符见表2.6。例如:
表2.6 转义特殊字符
字符串还有一个经常使用的函数len( ),其功能是返回字符串的长度。例如:
3.List(列表)型数据
Python的列表型数据功能强大,在进行网页内容获取的时候被频繁使用。列表由写在“[ ]”之间、用“,”分隔的元素构成。列表中元素的类型可以不同,最常用的元素类型是数字、字符串和嵌套列表(即列表中的一个元素是另一个列表)。定义列表类型的变量方法如下。
与字符串类似,也可以使用索引值表示列表中的元素。例如:
说明:
① “print(var9)”表示输出列表的全部元素。
② “var9[0]”表示列表的第1个元素。
③ “var9[2:]”表示列表的第3个至最后一个元素。
④ “var9*2”表示复制当前列表2次。
列表的常用函数有append( )、reverse( )、count( )、index( )、insert( )、remove( )和sort( )等。
函数append( )的功能是将参数追加入列表对象的结尾。reverse( )函数的功能是将列表对象中的元素按所在位置进行反转。count( )函数的功能是返回列表中某元素的个数。例如:
函数index( )的功能是返回参数在列表中的索引位置。函数insert( )的功能是在任何位置增加一个列表元素。函数remove( )的功能是删除列表元素。例如:
说明:
① 函数insert( )包含两个参数,第一个参数是索引值,第二个参数是插入内容。
② 函数remove( )只有一个参数,即删除的列表元素,若列表中包含参数,则删除列表中找到的第一个列表元素,如上例var9.remove("abc")只删除第一个元素"abc",而未删除第二个"abc"元素。若参数并不能在列表中找到,则返回错误提示数据。
思考:列表var9包含两个相同的元素'abc',则函数index('abc')返回哪个的索引值?
函数sort( )的功能是对列表元素进行从小到大的排序,若列表元素的数据类型不同,则无法排序(有些Python版本也支持数据类型不同的列表元素排序,如Python2.7.10),显示错误数据。例如:
说明:
① 函数sort( )出现无法排序的错误提示,是因为列表元素有字符串,还有整数和小数,而字符串和数值型数据是无法比较大小的。
② 函数sort( )使用“reverse=True”参数时,是按照从大到小降序排列。
③ 函数sort( )使用“key=len”参数时,是按照长度从小到大升序排列。
④ 单独使用var9的功能与print(var9)相同,功能是输出列表的全部元素。
Python语言支持的运算符包括算术运算符、比较(关系)运算符、赋值运算符、逻辑运算符、位运算符、成员运算符和身份运算符。赋值运算符在前面的案例中已经多次使用,算术运算符、比较(关系)运算符和逻辑运算符应用广泛。
4.算术运算符
算术运算符见表2.7。假设变量a赋值为23,变量b赋值为10,变量c赋值为“TV”。
表2.7 算术运算符
说明:
① 乘法运算符的左右两侧均为数字型数据时,表示两个数字相乘。当左侧为字符串、右侧为整数n时,表示复制左侧字符串n次。
②23除以10的商是2余数是3,所以取模运算“a % b=3”,而整除运算“a // b=2”。
5.比较(关系)运算符
比较运算符见表2.8。假设变量a赋值为23,变量b赋值为10。
表2.8 比较运算符
说明:比较运算符的运算结果只能是“True”或“False”。“True”或“False”都是Python关键字,首字母大写,且默认为蓝色显示。
6.逻辑运算符
逻辑运算符见表2.9。假设变量a赋值为23,变量b赋值为10,变量c赋值为0,变量d赋值为“True”,变量e赋值为“False”。
表2.9 逻辑运算符
说明:任何非零数字型数据均认为是逻辑值“True”,逻辑值“True”和“False”可以与数字型数据进行算术运算,此时逻辑值“True”被认为是数字1,“False”是数字0。
7.成员运算符
成员运算符见表2.10。假设变量a赋值为“abc”,变量b赋值为“Abc”(注意字符串的大小写),变量c赋值为列表['ABC','UCASS','abc']。
表2.10 成员运算符
2.7.4 条件语句
Python语言包含三种语句,最简单的是顺序语句,即按照语句的先后顺序执行。第二种是条件语句,根据条件进行判断和选择执行的语句。第三种是循环语句,根据条件决定执行的次数。
条件语句也称为分支语句或if语句,格式如下。
说明:
① 必须使用4个空格的缩进表示语句块的开始和结束。
② 条件和else后面的“:”必须书写。
③ 根据需要,决定elif语句的个数及是否包含else语句。
1.单分支条件语句
条件语句的使用方法有多种情况,最简单的单分支条件语句只包含一个if,没有elif和else。只有一个分支。例如,新建一个程序文件test.py。
程序运行结果如下:
说明:变量a赋值为整数10,输出时必须使用函数str(a)转换为字符串,才能使用“+”运算符。
2.双分支条件语句
双分支条件语句包含两个分支,根据条件是“True”还是“False”来决定执行的分支。例如:
程序运行结果如下:
说明:缩进表示语句块的开始和结束,最后一行语句没有任何缩进,不属于if语句,也不属于else语句,是单独的一条顺序语句,无论条件“a>0”的结果是“True”还是“False”,均执行该条语句。
3.多分支条件语句
多分支条件语句包含三个或以上的分支,根据条件结果执行相应的分支。例如:
程序运行结果如下:
说明:
① 判断变量a是否是零值的语句是“a==0”,不能写成“a=0”,前者“==”是比较运算符,后者“=”是赋值运算符。
② 本例中条件语句只包含一个elif分支,实际上可以根据需要包含多个elif分支,只有当前面的所有条件均不为“True”时才执行else语句。
③ 各条件不能有交集。
4.注释
注释是对程序代码的解释和说明。注释并不执行,对程序的运行结果也没有任何影响,主要用于帮助自己或他人更好地理解代码。注释要准确简洁,格式一致,尽量保证注释与所注释的代码相邻,一般在代码的上方或右侧进行注释。例如:
程序运行结果如下:
说明:
① 单行注释以“#”开头,可以在所注释代码的上方或右侧。
② 多行注释需要在注释的上面使用3个英文引号、下面使用3个英文引号。引号可以是单引号或双引号,但上下引号必须一致。
2.7.5 循环语句
在编写程序时经常需要完成大量的重复工作,为了减少代码的长度,提高程序可读性,降低复杂度,可以使用循环语句完成这类问题。
Python包含两种循环语句:for循环、while循环。
1.for循环语句
Python中的for循环语句可以方便地遍历一个序列的全部元素,如一个列表中的每个元素,一个字符串中的每个字符。例如:
遍历列表元素的代码如下:
程序运行结果如下:
说明:
① 程序共循环4次。第1次循环取出列表langs中的第一个元素'Java'并打印,然后依次取出第二个、第三个、第四个元素并打印。
② 循环语句中的变量c用于临时存储每次循环取出的元素,此变量名只需符合标识符规则即可,名字可以任意设定。
遍历列表元素的方法不止一种,也可以使用如下代码实现。
说明:
① 函数len(langs)用于返回langs列表的元素个数,本例返回“4”。
② 函数range(start,end,step)包含3个参数。start设置计数的起始值。end设置计数的结束值,但不包括end。step设置每次增加的间距,默认为1。本例的range(0,4)表示从0开始,每次增加1,包含1、2、3但不包含4,即打印langs[0]、langs[1]、langs[2]、langs[3],遍历了列表的全部元素。
遍历字符串的代码如下。
程序运行结果如下:
说明:
① 循环语句中的变量c用于临时存储字符串中的每个字符。
② 本循环语句共循环3次。
2.while循环语句
Python中,while循环语句包含一个执行条件,当条件满足时就执行某段程序,直至条件不再满足。例如:
使用while循环语句遍历列表元素的代码如下。
程序运行结果如下:
说明:
① 本例中的函数len(langs)的返回值是4。变量i的初始值是0,满足条件,则循环1次,变量i的值重新赋值为1;然后循环判断条件是否满足,直到变量i赋值为4时,条件不再满足,退出循环。本例共循环4次。
② 本例中的变量i必须在while循环语句前赋值,否则变量i没有赋值,无法进行条件判断。
循环语句while和for中经常使用break语句终止循环(即使满足循环条件也会停止执行)。continue语句用于跳出本次循环,执行下一次循环。注意,break语句将终止整个循环。例如:
程序运行结果如下:
说明:
① 程序的功能是从1开始的整数相加,当和大于10时不再相加跳出循环,打印输出。
② for循环语句的循环体包含两条语句。第一条是“sum= sum + i”,第二条是if语句,当条件“sum >10”的结果是“True”时,执行break语句,即条件满足退出for循环语句,执行for循环语句后面的print语句。
③ 程序最后的print语句的缩进格式表示这条语句不属于for循环,如该语句缩进,则属于for循环,该语句循环4次,输出如下。
例如,语句continue如下。
程序运行结果如下:
说明:
① 程序的功能是将1~10中的奇数相加,当超出10时不再相加跳出循环,打印输出。
② for循环语句的循环体包含两条语句。第一条是if语句,当条件“i %2==0”的结果是“True”时,即当变量i是偶数时,执行continue语句,跳出本次循环,即不执行第二条语句“sum= sum + i”,进入下一次循环。
循环语句还有一种包含else子句的用法,当循环条件不满足结束循环时执行,但循环被break语句终止时不执行。
输出20~30之间的质数的代码如下:
程序运行结果如下:
说明:
① 这是一个循环嵌套,即for循环语句中包含另一个for循环语句。
② 第二个for循环语句的范围是range(2,n//2),“n//2”表示n整除2的值。
③ 循环语句中的if语句的条件“n % x==0”表示当n能被x整除时,执行break语句终止内部的for循环,即不执行后面的else语句。但不影响外部for循环,即终止内部嵌套的for循环后,继续执行外部for循环。
④ 当内部for循环一直没有满足if条件,但因为超出range(2,n//2)范围而终止时,执行else语句,即n不能整除2~n//2的所有整数,则可判断其为质数。
思考:若将else语句缩进到与if语句同列,则运行结果如何?
2.7.6 输入和输出
Python语言经常使用print( )函数完成输出,使用函数input( )实现输入。函数print( )在前面的案例中已经多次使用,本节介绍如何使用该函数完成格式化输出,例如:
程序运行结果如下:
说明:
① 函数print( )中的“%”符号表示转换说明符的开始。转换说明符的具体含义见表2.11。
② 函数print( )还可以设置左对齐,显示正负号,设置最小字段宽度和精度等格式,具体参见帮助文档[41]。
表2.11 字符串格式化转换类型
函数input( )的功能是返回用户输入的字符串,默认的标准输入是键盘,每次仅读入一行文本。
程序运行结果如下:
说明:
① 函数input( )包含一个参数时用于提示用户输入的内容。
② 程序运行input( )时,需要用户手动输入内容并回车后才能继续执行其他语句。
2.7.7 文件的读/写
文件对象用于建立与磁盘文件的联系,可以实现文件内容的读取,将字符串写入文件,或将获取的网络数据使用文件对象存储,方便后续的修改和使用。
读/写文件前,先用open( )函数打开一个文件,该函数的功能是返回一个文件对象。其格式如下:
说明:
① 第一个参数表示文件的名字,第二个参数说明打开文件的模式,即如何使用该文件,该参数省略,表示文件以“r”模式打开。文件的打开模式见表2.12。文件的打开模式可以有多种组合,如“r”模式表示以只读方式打开文件,“r+”模式是文件既可读也可写,从文件头部开始写,覆盖原文件的内容,但不会创建不存在的文件。“w+”模式是文件既可读也可写,若文件存在,则覆盖整个文件,与“r+”模式不同的是,若文件不存在,则新建文件。
表2.12 模式参数
② 通常情况下,文件是以文本模式打开的,读写采用默认的UTF-8编码格式,以二进制模式打开的情况使用较少,一般以字节的形式进行读写操作。
文件对象file的常用函数见表2.13。
表2.13 文件对象的常用函数
例如,读取文件内容的代码如下:
说明:
① 代码的第1行以只读方式打开文件“test.txt”,函数open( )生成文件对象f。
② “f.name”的功能是返回文件对象f的文件名。
③ 函数f.read(10)从文件头部开始读取10字节后,赋值给变量line。
例如,将字符串写入文件的代码如下:
说明:
① 代码第2行以只写方式打开文件“test.txt”,若该文件不存在,则新建此文件。
② 代码“f. write(var1)”的功能是将变量var1的字符串写入对象f指向的文件“test.txt”。
③ 最后一行代码用于关闭文件。
例如,从一个文件中读取内容写入另一个文件的代码如下:
说明:
① 第1行缺少文件打开模式,默认表示文件以只读模式打开。
② 循环语句while多次执行,直到文件“input.txt”中的内容全部被读取。循环体中使用if语句判定是否退出循环,当内容全部读取后,再次读取时变量line的值为空,不符合条件,则使用语句break结束循环。
③ 最后2行代码分别关闭两个文件。