第3章Python 3语言基础 3.1Python 3简介 Python 是一个高层次的结合了解释性、编译性、交互性和面向对象4个特点的脚本语言。 Python 的设计具有极强的可读性,相比其他语言,Python经常使用英文关键字、标点符号,具有比其他语言更具特色的语法结构。 Python具有以下显著特点。 1. 解释性 这意味着开发过程中没有了编译这个环节。类似于PHP和JavaScript语言。 2. 交互性 这意味着用户可以在一个 Python 控制台终端(提示符>>>后)直接执行代码,如图3.1所示。 图3.1Python控制台终端编程 3. 面向对象 这意味着Python支持面向对象编程的风格或代码封装在对象中的编程技术。与其他主要语言(如Java)相比,Python以一种非常强大且简单的方式实现了面向对象编程。 4. 简单易学 Python是一种对初学者十分友好的语言,一个风格良好的Python程序如同英文段落一样易懂。Python的最大优点之一是具有伪代码的本质,它使用户在开发Python程序时专注于解决问题,而不是搞明白语言本身。 3.1.1Python 的发展历史 20世纪80年代末至90年代初,Python 由 Guido van Rossum在荷兰数学和计算机科学研究学会设计出来。 Python 本身是由诸多其他语言发展而来的,包括 ABC、Modula3、C、C++、Algol68、SmallTalk、UNIX Shell 和其他脚本语言。 当前,Python 由一个核心开发团队进行系列维护工作,但Guido van Rossum 仍然在其中发挥着至关重要的作用,指导Python的相关工作。 1989年,Guido van Rossum为消遣时间,决定为当时正构思的一个新脚本语言编写一个解释器,以Python命名该项目,使用C语言进行开发。 1991年,Python的第一个版本发布。此时Python已经具有了类、函数、异常处理、包含表和词典在内的核心数据类型以及以模块为基础的拓展系统。 1991—1994年,Python增加了lambda、map、filter和reduce模块。 1999年,Python的Web框架之祖——Zope发布。 2000年,Python加入了内存回收机制,构成了现在Python语言框架的基础。 2004年,Web框架 Django 诞生。 2006年,Python 2.5发布。 …… 2019年,Python 3.8发布。 2020年,对Python 2.0版本的支持停止。 3.1.2Python的应用 Python作为一种简单好用的编程语言,广泛应用于以下领域,如图3.2所示。 图3.2Python的应用领域 1. Web开发 Python经常被用于Web开发。例如,在mod_wsgi模块、Apache mod_wsgi模块上可以运行用Python编写的Web程序。还有一些Web框架(如Django、TurboGears、web2py等)可以让程序员轻松地开发和管理复杂的Web程序。 2. 系统运维 Python 在不断进化,它的功能已经延伸到IT运维的方方面面。Python拥有强大的脚本处理功能,它在操作Linux系统方面具有先天的优势。许多云平台、运维监控管理工具均使用Python开发,Python的自动化运维可以减少运维工程师的工作量,提高工作效率。 3. 科学计算 Python第三方库提供的NumPy、SciPy、Matplotlib等模块能让Python程序员快速编写科学计算程序。 4. 桌面软件 PyQt、PySide、wxPython、PyGTK是Python快速开发桌面应用程序的模块。 5. 游戏开发 除了在科学计算领域占据一席之地之外,Python在游戏、后台等领域也大放异彩。pygame是一组专门为编写游戏而设计的Python模块,可以使用户在Python语言中轻松地创建全功能的游戏和多媒体程序。 Python 3环境搭建 3.2环境搭建 3.2.1Python 3环境的搭建 关于Python 3环境搭建的讲解视频可扫描二维码观看。 Python 3 可应用于多平台,包括 Windows、Linux 和 Mac OS X。本节将讲解如何在本地搭建Python 3开发环境。 1. 在Windows环境下安装Python 1) Python 3的下载 Python 3最新源代码、二进制文档、新闻资讯等可以在Python的官方网站查看,Python的官方网站地址为https://www.python.org/,如图3.3所示。 图3.3下载Python的界面 选择下载版本,下载对应系统的可执行安装文件,如图3.4所示。 图3.4选择下载版本 2) Python的安装 双击下载的可执行文件python3.x.exe,按提示进行安装,直到安装完成。 安装Python的过程中会自动配置环境变量,如果没有自动生成,可以手动配置环境变量。右击“我的电脑”图标,在弹出的快捷菜单中选择“属性”命令,弹出“系统属性”对话框,在对话框中选择“高级”选项卡,单击“环境变量”按钮,如图3.5所示。 图3.5设置环境变量 在变量名为Path的变量值的尾部添加Python 3安装目录即可,如图3.6所示。 图3.6添加环境变量 3) 验证 验证Python是否安装成功,可以通过在控制台终端输入python V的方式进行验证,如果出现Python安装版本,则说明Python安装成功,如图3.7所示。 图3.7验证是否安装成功 2. 在Linux环境下安装Python 在Linux系统中,一般情况下都预装有Python编译器,但是这个预装的Python版本一般比较低,许多特性都没有,如果要使用新版本的Python必须重新安装,如下所示: [root@Master001 ~]# python -V Python 2.6.6 [root@Master001 ~]# 注意,安装新的Python版本时,不需要删除旧的Python版本,因为Linux系统中有些命令仍需要旧的Python版本的支持,例如yum。 下载Python安装包可以在Python官方网站下载,也可以使用wget工具下载。 (1) 在Python官方网站下载,地址为https://www.python.org/downloads/,如图3.8所示。 图3.8下载Linux版本的Python (2) 使用wget工具下载资源在Linux系统中是最常用的下载方法之一。在使用wget命令之前需要先安装wget工具,wget工具可以使用yum命令进行安装,操作方法如下: [root@Master001 ~]# yum install -y wget 验证是否安装wget: [root@Master001 ~]# rpm -qa | grep wget wget-1.12-10.el6.x86_64 使用wget命令获取安装包: [root@Master001 ~]# wget https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tgz (3) 安装Python。 将wget下载的Python包解压: [root@Master001 software]# pwd /root/software [root@Master001 software]# tar -zxvf Python-3.6.2.tgz 配置configure文件,进入Python解压目录,执行configure命令。因为执行configure命令需要gcc工具的支持,所以需要先安装gcc工具。 [root@Master001 Python-3.6.2]# yum -y install gcc 执行configure命令: [root@Master001 Python-3.6.2]# ./configure configure命令执行后会在当前目录生成Makefile文件,该文件将在make解析时使用。 编译完成后不要着急执行make命令,因为pip工具在下载安装时需要SSL的支持,默认的SSL与系统自带的SSL不一致,因此会导致pip工具在使用过程中不能正常下载。 配置SSL证书。使用vim命令打开Pythonxx/Modules/Setup文件,该文件必须要执行configure命令才能生成。打开Setup将SSL的地址修改为系统自带的SSL地址即可。 查询SSL地址,如图3.9所示。 [root@Master001 Python-3.6.2]# openssl version -a 图3.9查询SSL地址 修改SSL,如图3.10、图3.11所示。 [root@Master001 Python-3.6.2]# vim Modules/Setup 图3.10SSL修改前 图3.11SSL修改后 使用make工具编译源代码,执行make命令需要openssl和openssldevel的支持。 [root@Master001 Python-3.6.2]# yum -y install openssl.x86_64 openssl-devel.x86_64 [root@Master001 Python-3.6.2]# make make install命令用于安装make编译好的源代码。 [root@Master001 Python-3.6.2]# make install 使用whereis命令查询Python 3的安装路径,若查询到则说明Python 3安装成功,如图3.12所示。 图3.12查询Python 3的安装路径 Python 3编译安装完成后,默认的安装目录是在/usr/local/bin和/usr/local/lib目录下。如果想要卸载刚安装好的Python编译器,直接删除这两个目录即可,如图3.13所示。 图3.13Python 3的安装位置 (4) 配置Python 3环境。 Hadoop Streaming工具提交MapReduce任务时需要Python 3编译器的支持,集群默认是在/usr/bin下找指定的Python 3编译器,但是/usr/bin中只有Python 2的编译器,所以在运行作业时可能会出现语法错误。为了解决这个问题,需要给Python 3的执行命令添加软链接到/usr/bin目录。 将Python 3可执行文件同步到/usr/bin目录中: [root@Master001 Python-3.6.2]# ln -s /usr/local/bin/python3 /usr/bin/python3 将pip3可执行文件同步到/usr/bin目录中: [root@Master001 Python-3.6.2]# ln -s /usr/local/bin/pip3 /usr/bin/pip3 PyCharm安装与使用 3.2.2PyCharm 关于PyCharm安装与使用的讲解视频可扫描二维码观看。 1. 安装PyCharm PyCharm是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高效率的工具,如调试、语法高亮、目录管理、代码跳转、智能提示、自动完成、单元测试、版本控制等。此外,该IDE还提供了一些高级功能,以用于支持Django框架下专业Web的开发。 官方网站下载地址为https://pycharm.en.softonic.com/。 下载PyCharm时有两种选择: 一种是专业版(Professional); 另一种是社区版(Community)。虽然社区版PyCharm比专业版PyCharm的功能少一些,但是社区版PyCharm是免费的。对于学习而言,社区版的功能完全能够满足用户实际需求,所以可以选择社区版进行下载,如图3.14所示。 图3.14选择PyCharm版本 (1) 运行PyCharm安装文件。双击可执行文件pycharmcommunity2019.3.2.exe即可运行该文件。 (2) 单击Browse按钮,修改安装路径,单击Next按钮,如图3.15所示。 图3.15设置安装路径 (3) 在弹出的对话框中勾选Create Desktop Shortcut复选框用于创建桌面快捷方式,勾选Create Associations复选框用于创建关联文件,如图3.16所示。 图3.16选择安装方式 在图3.16中,配置完成后单击Next按钮进入下一项配置,在下一项配置中单击Install按钮进行软件安装。 2. 创建PyCharm项目 (1) 双击PyCharm Community Edition 2019.3.2 x64图标,打开PyCharm工具,如图3.17所示。 (2) 单击Create New Project按钮,创建新项目,如图3.18所示。 (3) 设置Python项目存放位置,并选择所需要使用的解释器,如图3.19所示。 (4) 选择已经安装的Python解释器和接口,如图3.20~图3.22所示。 图3.17双击PyCharm Community Edition 2019.3.2 x64图标 图3.18创建新项目 图3.19设置Python项目存储位置 图3.20Python解释器 图3.21选择Python解释器 图3.22修改Python解释器后的效果 (5) 单击Create按钮,创建Python项目。 (6) 创建Python文件,编写第一个Python项目,如图3.23 所示。 图3.23创建项目过程 语法规范 3.3基础语法 3.3.1语法规范 关于语法规范的讲解视频可扫描二维码观看。 1. 注释 代码更多是用来“读”而不是用来“写”的。良好的编码规范可以使项目、模块或函数保持一致,从而提高Python代码的可读性。 注释分为单行注释与多行注释。示例代码如下: # 这是单选注释 print("学到教育") ''' 多行注释可以用3个单引号 ''' """ 多行注释也可以使用3个双引号 在Python中大多数情况单引号和双引号的作用一样, 均代表字符串 """ 2. 缩进 每级缩进用4个空格,Python不需要使用大括号({})来组织代码,完全依靠缩进。因此,缩进的格式非常重要,如果使用的缩进不是4个空格,则会报语法错误。在开发过程中,可以使用Tab键代替4个空格。 示例代码如下: a = 5 b = 3 if a > b: print("大于") else: print("小于") 输出结果: 大于 3. 分号 Python不严格要求使用分号,理论上应该是每行一句代码。每行代码后面可以添加分号,也可以不添加分号,尽量不要多句代码放在一行。如果放在一行,则需要添加分号把它们隔开。 示例代码如图3.24所示。 图3.24分号使用示例 通过图3.24可知,虽然在Python的代码中加上分号后仍能够正常运行,但是Python编译器建议去掉分号。 4. 标识符 标识符是在程序中对变量、常量、类、方法、参数等命名时使用的名字。命名时应该遵循以下规则: (1) 标识符由字母、下画线、数字组成,且不能以数字开头。 (2) Python对大小写敏感,a和A是完全不同的。 (3) 不能使用Python关键字命名。 (4) 命名应该产生见名知义的效果。 (5) 命名推荐使用驼峰式命名(studentName)和下画线命名(student_name)。 5. 多行语句 Python语句中一般以新行作为语句的结束符,也可以使用斜杠(\)将一行语句划分为多行显示。 示例代码如下: itemOne = 1 itemTwo = 2 itemThree = 3 total = itemOne + \ itemTwo + \ itemThree print(total) 输出结果: 6 语句中包含[]、{}、()符号的则不需要使用多行连接符。 days = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"] print(days) 输出结果: ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'] 6. Python引号 Python可以使用单引号、双引号、三引号来表示字符串,开始与结束的引号必须是同一类型。 其中,三引号可以由多行组成,是编写多行文本的快捷语法,常用于文档字符串,也可以当成多行注释,如图3.25所示。 图3.25引号使用示例 7. 输出 a = "学到" b = "教育" print("换行输出: ") print(a) print(b) print("不换行输出: ") print(a, b) 输出结果: 换行输出: 学到 教育 不换行输出: 学到 教育 当Python使用加号进行连接时,只能连接同一类型的值,如果连接不同类型的值,将会出现错误,如图3.26所示。 图3.26输出结果 print()函数提供sep与end参数控制输出结果。 sep: 分隔值与值,默认是一个空格。 end: 为末尾传递一个指定的字符串。 示例代码如下: print("AA", "BB", "CC", sep=":") print("DDD") print("-----------------------") print("AA", "BB", "CC", end=":") print("DDD") 输出结果: AA:BB:CC DDD ----------------------- AA BB CC:DDD 数据类型 3.3.2数据类型 关于数据类型的讲解视频可扫描二维码观看。 Python中的变量不需要声明,但每个变量在使用前都必须赋值,赋值以后该变量才会被创建。 在Python中,变量就是变量,变量没有类型,只有为它赋值后,才会根据值为它推导出类型。 等号(=)用来给变量赋值; 等号左边是变量名,等号右边是存储在变量中的值。 示例代码如下: a = 100# 整型变量 b = 100.0 # 浮点型变量 c = "学到教育"# 字符串变量 d = 'A' # 字符串变量,等同于"A" f = True# 布尔类型变量 在Python中允许同时为多个变量赋值。 创建一个整型对象,值为100,将100赋值给c变量后,又将c变量赋值给b变量,最后把b变量赋值给a变量。示例代码如下: a = b = c = 100 print(a, b, c) 输出结果: 100 100 100 也可以为多个变量指定多个值。示例代码如下: a, b, c = 1, 99.8, "学到" print(a, b, c) x, y = (20, 100) print(x, y) a1, b1, c1, d1 = {1, 2, 3, 4} print(a1, b1, c1, d1) 输出结果: 1 99.8 学到 20 100 1 2 3 4 在Python中定义了6个标准类型,用于存储各种类型的数据,其中又分为不可变数据类型和可变数据类型。不可变数据类型有Number(数字)、String(字符串)、Tuple(元组); 可变数据类型有List(列表)、Dictionary(字典)、Set(集合)。 1. 条件语句 Python条件语句是通过一条或多条语句的执行结果(true或false)来决定执行的代码块。 执行流程如图3.27所示。 图3.27条件语句流程图 Python编程中if语句用于控制程序的执行,基本形式为: if 判断条件: 语句块… else: 语句块… 示例代码如下: flag = "A" name = "张三" if name == "李四": flag = "B" else: print(name) print(flag) 输出结果: 张三 A 因为Python不支持switch语句,所以多个条件判断时只能用elif来实现判断。当需要多个条件同时判断时,可以使用or或者and。 当判断条件为多个值时,可以使用以下形式: if 判断条件1: 语句块1… elif 判断条件2: 语句块2… elif 判断条件3: 语句块3… else: 语句块… 示例代码如下: inputAge = input("请输入您的年龄: ") age = int(inputAge) print("年龄: ", age) if(age >= 0) and (age <= 12): print("儿童") elif(age >= 12) and (age <= 18): print("青少年") elif(age >= 18) and (age <= 150): print("成年人") else: print("年龄不正确") 输出结果: 请输入您的年龄: 10 年龄: 10 儿童 Python中支持if语句的嵌套,可以在对条件进行判断之后,再次对条件进行判断。示例代码如下: strA = ["A", "张三", 22] if strA[0] == "A": if strA[1] == "张三": strA[1] = "李四" print(strA) else: print(strA) else: print(strA[1]) 输出结果: ['A', '李四', 22] 2. 循环语句 在Python中只提供了for循环和while循环两种循环语句。 循环语句允许多次执行一个语句或语句组。循环语句流程如图3.28所示。 图3.28循环语句流程图 while循环在给定的判断条件为true时执行循环体,否则退出循环体。示例代码如下: a = 0 while a<= 5: print("每次输出的值: ", a) a += 1 输出结果: 每次输出的值: 0 每次输出的值: 1 每次输出的值: 2 每次输出的值: 3 每次输出的值: 4 每次输出的值: 5 “:=”为赋值运算符,因形似海象,所以被称为海象运算符。海象运算符常在while、if等语句中使用。示例代码如下: a = 0 while (a := a + 1) <= 5: print("每次输出的值: ", a) 输出结果: 每次输出的值: 0 每次输出的值: 1 每次输出的值: 2 每次输出的值: 3 每次输出的值: 4 每次输出的值: 5 在Python中,while…else在循环条件为false时执行else语句块。示例代码如下: count = 0 while count < 5: print("输出的值: ", count) count = count + 1 else: print("最后输出结果: ", count) 输出结果: 输出的值: 0 输出的值: 1 输出的值: 2 输出的值: 3 输出的值: 4 最后输出结果: 5 for循环可以遍历任何序列的项目,如一个列表或者一个字符串。for循环的语法格式如下: for 迭代变量in 列表 语句块… for循环的示例代码如下: sVal1 = "www.baidu.com" for a in sVal1: print(a, end="*") print() sVal2 = ["Java", "Python", "Scala", "Spark", "Hadoop"] for b in sVal2: print("遍历集合的值: ", b) 输出结果: w*w*w*.*b*a*i*d*u*.*c*o*m* 遍历集合的值: Java 遍历集合的值: Python 遍历集合的值: Scala 遍历集合的值: Spark 遍历集合的值: Hadoop for循环还可以通过索引迭代方式遍历集合元素。其中len()函数用于返回列表长度,range()函数用于返回一个序列的数。示例代码如下: sVal1 = "www.baidu.com" for a in range(len(sVal1)): print(sVal1[a], end="*") print() sVal2 = ["Java", "Python", "Scala", "Spark", "Hadoop"] for b in range(len(sVal2)): print("遍历集合的值: ", sVal2[b]) 输出结果: w*w*w*.*b*a*i*d*u*.*c*o*m* 遍历集合的值: Java 遍历集合的值: Python 遍历集合的值: Scala 遍历集合的值: Spark 遍历集合的值: Hadoop range()函数用于返回整数序列的对象,语法格式如下: range(stop) range(start, stop [, step]) 参数如下。 start: 计数从start开始,默认从0开始。 stop: 计数到stop结束,但不包括stop。 step: 步长,默认为1。 示例代码如下: print(range(20)) print(range(10, 20)) print(range(10, 20, 2)) print(list(range(10, 20, 2))) 输出结果: range(0, 20) range(10, 20) range(10, 20, 2) [10, 12, 14, 16, 18] 在Python中,for…else中的else表示else语句在for语句正常执行完的前提下再执行。示例代码如下: for a in range(5): print("值: ", a) else: print("for循环退出") 输出结果: 值: 0 值: 1 值: 2 值: 3 值: 4 for循环退出 Python语言允许在一个循环体内嵌入另一个循环。示例代码如下: # for循环嵌套 strVal = [["张三", "女", 20], ["李四", "男", 18], ["王五", "男", 22]] for a in strVal: for b in range(len(a)): print(a[b], end="\t") print("--------------------") # while循环嵌套 i = 0 while i < len(strVal): print(strVal[i]) j = 0 while j < len(strVal[i]): print(strVal[i][j]) j = j + 1 i = i + 1 输出结果: 张三女20李四男18王五男22-------------------- ['张三', '女', 20] 张三 女 20 ['李四', '男', 18] 李四 男 18 ['王五', '男', 22] 王五 男 3. 循环控制语句 循环控制语句可以更改语句的执行顺序,Python支持的循环控制语句如表3.1所示。 表3.1循环控制语句 控 制 语 句 描述 break 在语句块执行过程中终止循环,并且跳出整个循环 continue 在语句块执行过程中终止当前循环,跳出该次循环,执行下一次循环 pass 空语句,为了保持程序结构的完整性 Python中的break语句就像是在Java语言中打破了最小封闭的for或while循环。 break语句用来终止循环语句,即循环条件中没有false条件或者序列还没被完全递归完,也会被停止执行循环语句。 break语句用在while和for循环中,如果用户使用嵌套循环,那么break语句将停止执行最深层的循环,并开始执行下一行代码。 示例代码如下: sVal = "baidu" for a in sVal: if a == "d": print("遇到字母d,退出系统") break print(a) 输出结果: b a i 遇到字母d,退出系统 Python中的continue语句是指跳出本次循环。continue语句用来告诉Python跳过当前循环,然后继续进行下一轮循环。continue语句可以用在while和for循环中。 示例代码如下: for a in range(5): for b in range(5): if b == 2: continue print(b, end="") print("外层循环: ", a) 输出结果: 0 1 3 4 外层循环: 0 0 1 3 4 外层循环: 1 0 1 3 4 外层循环: 2 0 1 3 4 外层循环: 3 0 1 3 4 外层循环: 4 pass是空语句,其作用是保护程序结构的完整性。pass不做任何事情,一般用作占位语句。 示例代码如下: for a in range(5): if a == 3: pass print("外层循环: ", a) 输出结果: 外层循环: 0 外层循环: 1 外层循环: 2 外层循环: 3 外层循环: 4 Number数据类型 3.3.3Number数据类型 关于Number数据类型的讲解视频可扫描二维码观看。 Python 中的Number数据类型用于存储数值。 数据类型是不允许被改变的,这就意味着如果改变Number数据类型的值,将需要重新分配内存空间。 以下示例表示在变量赋值时Number对象将被创建。 var1 = 10 var2 = 20 1. del语句 del语句用于删除Number对象引用。示例代码如下: var1 = 10 var2 = 20 var3 = 30 print(var1, var2, var3) del var1 del var2, var3 print(var1, var2, var3) 输出结果: 10 20 30 Traceback (most recent call last): File "D:/Users/Python/PythonSpark/Test.py", line 8, in print(var1, var2, var3) NameError: name 'var1' is not defined 2. math模块 Python中数学运算常用的函数基本都在math模块中,math模块为浮点数提供了许多数学运算函数。因此,在使用math模块前必须先导入math模块。 示例代码如下: import math print(max(1, 2, 30, 4, 5), "找出一组数据中的最大值") print(min(1, 2, 30, 4, 5), "找出一组数据中的最小值") print(math.floor(4.9), "截取整数值") print(math.ceil(4.9), "向上取整") print(round(3.1456546, 2), "四舍五入,2代表保留两位小数,默认取整") print(abs(-10), "返回数字的绝对值") print(math.fabs(-10), "返回数字的绝对值") print(math.sqrt(9), "返回指定数字的平方根") print(math.modf(3.14), "分离指定值的小数与整数") 输出结果: 30 找出一组数据中的最大值 1 找出一组数据中的最小值 4 截取整数值 5 向上取整 3.15 四舍五入,2代表保留两位小数,默认取整 10 返回数字的绝对值 10.0 返回数字的绝对值 3.0 返回指定数字的平方根 (0.14000000000000012, 3.0) 分离指定值的小数与整数 3. random模块 随机数可以用于数学、游戏、安全等领域中,也经常被嵌入算法中,用以提高算法效率,并提高程序的安全性。 示例代码如下: import random # 在[0, 9)范围内随机生成一个整数 print(random.choice(range(0, 10))) # 在[100, 200)范围内随机生成一个整数,步长为10 print(random.randrange(100, 200, 10)) # 在[0, 1)范围内随机生成一个浮点数 print(random.random()) # 在[10, 100)范围内随机生成一个浮点数 print(random.uniform(10, 100)) # 将列表中的所有元素随机排序 a = [1, 7, 4, 5, 6, 7] print("随机排序前: ", a) random.shuffle(a) print("随机排序后: ", a) 输出结果(每次结果都随机): 1 130 0.3317805641157606 66.44410419643317 随机排序前: [1, 7, 4, 5, 6, 7] 随机排序后: [6, 1, 4, 7, 5, 7] 字符串 3.3.4字符串 关于字符串的讲解视频可扫描二维码观看。 1. 定义访问字符串 字符串是Python中最常用的数据类型。创建字符串十分简单,只需为变量分配一个值即可,可以使用单引号或双引号来创建字符串。在Python中不支持单字符类型,单字符在Python中是作为一个字符串使用的。示例代码如下: a = '学到教育' b = "www.baidu.com" # 获取指定字符串的第一个字符 print(a[0]) # 获取指定字符串的最后一个字符 print(a[len(a): 1]) # 获取[4, 10)范围内的字符 print(b[4:10]) # 拼接字符串。Python中只允许同类型拼接 print(a + b) print(a, b, sep="") 输出结果: 学 育 baidu 学到教育www.baidu.com 学到教育www.baidu.com 2. 转义符 需要使用特殊字符时,可以在字符串中用转义符(\)进行特殊字符转换,这样Python就会将特殊字符当成普通字符使用。 示例代码如下: print("转义反斜杠\\") print("转义单引号\'") print("转义双引号\"") print("转义制表符\\t") print("转义换行符\\n") 输出结果: 转义反斜杠\ 转义单引号' 转义双引号" 转义制表符\t 转义换行符\n 3. 字符串内建函数 以下是Python字符串常见内建函数,可以使用help(str)查看str函数库中的函数。 1) find()函数 find()函数用于查询指定字符的索引,包含返回开始的索引值,可指定范围查询。 示例代码如下: d = "www.baidu.com" # 返回指定字符的索引,如果找到多个字符,则返回第一个字符的索引 print(d.find("w")) # 指定范围查询 print(d.find("w", 1, len(d): 1)) 输出结果: 0 1 2) join()函数 join()函数用于将列中的元素以指定的字符连接生成一个新的字符串。 示例代码如下: a = "-" b = ("张三", "20", "成都") print(a.join(b)) 输出结果: 张三-20-成都 3) split()函数 split()函数指定分隔符对字符串进行切片,返回集合。 示例代码如下: a = "张三 李四 王五 赵六 孙七 周八" # 对字符串按空格分隔返回数据集 print(a.split("")) # 对字符串按空格限次数分隔,返回数据集 print(a.split("", 2)) 输出结果: ['张三', '李四', '王五', '赵六', '孙七', '周八'] ['张三', '李四', '王五 赵六 孙七 周八'] 4) 其他常用函数 示例代码如下: a = " Xue Dao " # 转换为全小写 print(a.lower()) # 转换为全大写 print(a.upper()) # 获取字符串长度 print(len(a)) # 去除左边空格 print(a.lstrip()) # 去除右边空格 print(a.rstrip()) # 替换所有空格为- print(a.replace("", "-")) # 替换1次空格为- print(a.replace("", "-", 1)) 输出结果: xue dao XUE DAO 9 Xue Dao Xue Dao -Xue-Dao- -Xue Dao 列表 3.3.5列表 关于列表的讲解视频可扫描二维码观看。 1. 定义列表 序列是Python中最基本的数据结构,序列中的每个元素都分配一个索引,第一个索引是0,第二个索引是1,以此类推。列表的数据项不需要具有相同的类型,创建一个列表,只要把用逗号分隔的不同的数据项使用方括号括起来即可。 示例代码如下: # 定义字符串列表 a = ["Python", "Java", "C#", "C语句"] # 定义Number类型列表 b = [1, 2, 3, 4, 5, 6] # 定义混合类型列表 c = ["张三", 20, "成都"] print(a, b, c, sep="\n") # list可以定义一个空列表,也可以将其他可迭代的值转换为列表 d = list() print("空列表", d) 输出结果: ['Python', 'Java', 'C#', 'C语句'] [1, 2, 3, 4, 5, 6] ['张三', 20, '成都'] 空列表 [] 2. 访问列表中的值 使用下标索引可以访问列表中的元素值,也可以使用取值范围访问指定范围内的元素值。 示例代码如下: # 定义字符串列表 a = ["Python", "Java", "C#", "C语句"] # 获取下标为1的元素 print(a[1]) # 获取下标为2到下标为4范围内的元素 print(a[2:4]) # 利用for循环遍历所有元素 for b in a: print("for循环遍历结果: ", b) 输出结果: Java ['C#', 'C语句'] for循环遍历结果: Python for循环遍历结果: Java for循环遍历结果: C# for循环遍历结果: C语句 3. 更新、删除列表 列表是可变数据类型,可以通过列表对列表数据进行修改或更新。可以使用append()方法将元素添加到列表项中,也可以使用del语句删除列表中的元素。 示例代码如下: # 定义字符串列表 a = ["Python", "Java", "C#", "C语句"] # 在a列表尾部追加元素 a.append("PHP") print(a) # 更新下标为1的元素值 a[1] = "Java语言" print(a) # 删除指定下标中的元素 del a[2] print(a) 输出结果: ['Python', 'Java', 'C#', 'C语句', 'PHP'] ['Python', 'Java语言', 'C#', 'C语句', 'PHP'] ['Python', 'Java语言', 'C语句', 'PHP'] 4. 列表操作符 列表中+和*操作符与字符串操作符相似。+用于组合列表,*用于重复列表。 示例代码如下: # 定义字符串列表 a = ["Python", "Java", "C#", "C语句"] b = ["Scala", "PHP"] # 获取a列表中元素的个数 print(len(a)) # 组合两个列表,生成新的列表 print(a + b) # 重复列表 print(a * 3) # 判断元素是否在集合中 print("Java" in a) 输出结果: 4 ['Python', 'Java', 'C#', 'C语句', 'Scala', 'PHP'] ['Python', 'Java', 'C#', 'C语句', 'Python', 'Java', 'C#', 'C语句', 'Python', 'Java', 'C#', 'C语句'] True 5. 嵌套列表 嵌套列表即在列表中创建其他列表,类似Java中的二维数组。 示例代码如下: a = [["张三", 20, "成都"], ["李四", 22, "北京"], ["王五", 18, "上海"]] # 打印列表中所有数据 print(a) # 打印索引为0的列表的所有数据 print(a[0]) # 打印具体元素 print(a[0][0]) 输出结果: [['张三', 20, '成都'], ['李四', 22, '北京'], ['王五', 18, '上海']] ['张三', 20, '成都'] 张三 6. 列表常用函数 列表常用函数示例如下: a = [2, 3, 4, 5, 6, 5, 4, 4, 5, 2, 2] b = [100, 200] c = (300, 600) # 统计5在列表中出现的次数 print(a.count(5)) # 将b列表追加到a列表中 a.extend(b) print(a) # 将c元组追加到a列表中 a.extend(c) print(a) # 在a列表中找到第一个元素为5的下标值 print(a.index(5)) # 将999元素值插入下标为0的位置 a.insert(0, 999) print(a) # 移除最后一个元素 a.pop() print(a) # 移除指定位置元素 a.pop(0) print(a) # 删除第一个匹配的元素 a.remove(5) print(a) # 反转列表中的所有元素 a.reverse() print(a) # 从a列表中复制一个新列表 d = a.copy() print(d) # 清空a列表中的所有元素 a.clear() print(a) 输出结果: 3 [2, 3, 4, 5, 6, 5, 4, 4, 5, 2, 2, 100, 200] [2, 3, 4, 5, 6, 5, 4, 4, 5, 2, 2, 100, 200, 300, 600] 3 [999, 2, 3, 4, 5, 6, 5, 4, 4, 5, 2, 2, 100, 200, 300, 600] [999, 2, 3, 4, 5, 6, 5, 4, 4, 5, 2, 2, 100, 200, 300] [2, 3, 4, 5, 6, 5, 4, 4, 5, 2, 2, 100, 200, 300] [2, 3, 4, 6, 5, 4, 4, 5, 2, 2, 100, 200, 300] [300, 200, 100, 2, 2, 5, 4, 4, 5, 6, 4, 3, 2] [300, 200, 100, 2, 2, 5, 4, 4, 5, 6, 4, 3, 2] [] 元组 3.3.6元组 关于元组的讲解视频可扫描二维码观看。 Python的元组与列表基本类似,但也有不同,不同之处在于元组的元素不能修改。元组使用小括号,而列表使用方括号。元组的创建十分简单,只需在括号中添加元素,并用逗号隔开即可。 1. 定义元组 示例代码如下: # 定义同一类型的元素 a = ("张三", "女", "20") # 定义不同类型的元素 b = ("张三", "女", 20) # 元组可以不需要括号 c = "张三", "女", 20 print(a, b, c) 输出结果: ('张三','女','20') ('张三','女',20) ('张三','女',20) 2. 访问元组 可以使用下标索引来访问元组中的值。 示例代码如下: a = ("张三", "女", "20", "成都", "软件开发工程师") # 获取下标为0的值 print(a[0]) # 获取[1, 3)范围内的元组 print(a[1:3]) # 遍历元组数据 for b in a: print(b, end="\t") 输出结果: 张三 ('女', '20') 张三女20成都软件开发工程师 3. 修改元组 元组为不可变类型,不允许修改。但是,可以使用+运算符连接两个元组,从而生成另一个新的元组。 示例代码如下: a = ("张三", "女", "20") b = ("成都", "软件开发工程师") c = a + b print(c) 输出结果: ('张三','女','20','成都','软件开发工程师') 4. 删除元组 由于元组是不可变类型,因此元组中的元素值是不允许被删除的,但可以使用del语句来删除整个元组。 示例代码如下: a = ("张三", "女", "20") b = ("成都", "软件开发工程师") del a c = a + b print(c) 输出结果: Traceback (most recent call last): File "D:/Users/Python/PythonSpark/Test.py", line 5, in c = a + b NameError: name 'a' is not defined 5. 元组常用内置函数 元组常用内置函数示例如下: a = ("张三", "女", "20", "成都", "软件开发工程师") b = [1, 2, 4] # 获取a元组中的元素个数 print(len(a)) # 获取元组中的最大值 print(max(a)) # 获取元组中的最小值 print(min(a)) # 将列表转换为元组 print(tuple(b)) 输出结果: 5 软件开发工程师 20 (1, 2, 4) 字典 3.3.7字典 关于字典的讲解视频可扫描二维码观看。 字典是另一种可变容器,可存储任意类型的对象。字典的每个元素都是键值对,每个元素之间都用逗号分隔,其中键必须是唯一的,但值则不必须唯一。值可以取任何数据类型,但键必须是不可变的,如字符串、数字或元组。 1. 访问字典 把相应的键放入方括号中,可以获取相应的值。 示例代码如下: a = {"name": "张三", "age": 20, "地址": "成都"} print(a["name"], a["地址"]) b = {1: "成都", 2: "上海", 3: "北京"} print(b[1], b[3]) c = {(1, 2, 3): "成都", (4, 5, 6): "北京"} print(c[(1, 2, 3)]) 输出结果: 张三 成都 成都 北京 成都 2. 更新字典 更新字典包括对字典中元素的增、删、改操作。示例代码如下: a = {"name": "张三", "age": 20, "地址": "成都"} # 向字典中添加新值 a["tel"] = "15008208000" print(a) # 修改字典中某个元素的值 a["age"] = 30 print(a) # 删除指定key的值 del a["地址"] print(a) 输出结果: {'name': '张三', 'age': 20, '地址': '成都', 'tel': '15008208000'} {'name': '张三', 'age': 30, '地址': '成都', 'tel': '15008208000'} {'name': '张三', 'age': 30, 'tel': '15008208000'} 3. 字典常用内置函数 以下为字典常用内置函数的示例: a = {"name": "张三", "age": 20, "地址": "成都"} # 获取字典中元素的个数 print(len(a)) # 复制字典 b = a.copy() print(b) # Python字典中fromkeys()方法用于创建一个新字典,以序列seq中元素作为字典的键,value # 为字典所有键对应的初始值 c = ("name", "sex", "tel") d = "初始值" f = a.fromkeys(c, d) print(f) # get()方法用于返回指定键的值,如果值不在字典中则返回默认值 print(a.get("name")) print(a.get("name2", "默认值")) # items()方法用于返回可遍历的元素数组 print(a.items()) # keys()方法用于返回key值的可迭代对象,可以使用list()转换为列表 a2 = a.keys() print(list(a2)) # values()方法用于返回values值的可迭代对象 a3 = a.values() print(list(a3)) # update()方法用于将一个字典追加到另一个字典中 str2 = {"a":"A", "b":"b"} a.update(str2) print(a) # pop()方法用于删除字典中给定key所对应的值 a.pop("name") print(a) # 清除字典中所有元素 a.clear() print(a) 输出结果: 3 {'name': '张三', 'age': 20, '地址': '成都'} {'name': '初始值', 'sex': '初始值', 'tel': '初始值'} 张三 默认值 dict_items([('name', '张三'), ('age', 20), ('地址', '成都')]) ['name', 'age', '地址'] ['张三', 20, '成都'] {'name': '张三', 'age': 20, '地址': '成都', 'a': 'A', 'b': 'b'} {'age': 20, '地址': '成都', 'a': 'A', 'b': 'b'} {} 集合 3.3.8集合 关于集合的讲解视频可扫描二维码观看。 集合是一个无序、不重复的元素序列,可以使用花括号创建集合,集合元素只能为不可变类型。 1. 更新集合 可以通过对集合进行增、删、改操作来更新集合。 示例代码如下: a = {"张三", "李四", "张三", "王五"} # 集合内元素不能重复 print(a) # 往集合中添加元素 a.add("赵六") print(a) # 往指定集合中添加列表 a.update({"孙七", "周八"}) print(a) # 往指定集合中添加元组 a.update(("孙一一", "周杰")) print(a) # 往指定集合中添加字典 a.update({"name": "王伦"}) print(a) # 不能添加可变类型,如Number类型 a.update(1) print(a) 输出结果: TypeError: 'int' object is not iterable {'李四', '张三', '王五'} {'李四', '张三', '赵六', '王五'} {'张三', '赵六', '王五', '孙七', '李四', '周八'} {'张三', '赵六', '孙一一', '王五', '孙七', '周杰', '李四', '周八'} {'张三', '王五', '周八', '周杰', '李四', '赵六', '孙一一', '孙七', 'name'} Traceback (most recent call last): File "D:/Users/Python/PythonSpark/Test.py", line 23, in a.update(1) Process finished with exit code 1 2. 移除元素 示例代码如下: a = {"张三", "李四", "张三", "王五"} # remove()用于从集合中移除指定的元素,如果元素不存在,则会发生错误 a.remove("张三") print(a) # discard()用于从指定集合中移除指定的元素,如果元素不存在,则不会发生错误 a.discard("张三三") print(a) # pop()用于设置随机删除集合中的一个元素,集合的pop()方法会对集合进行无序的排序,然后 # 将这个无序排序的第一个元素删除 a.pop() print(a) 输出结果: {'王五', '李四'} {'王五', '李四'} {'李四'} 3. 集合常用内置函数 以下为集合常用内置函数的示例: a = {"张三", "李四", "张三", "王五"} b = {"李四", "王一一"} # union()用于返回两个集合的并集 print(a.union(b)) # intersection()用于返回两个集合的交集 print(a.intersection(b)) # copy()用于复制一个集合 c = a.copy() print(c) # clear()用于清空指定集合 a.clear() print(a) 输出结果: {'王一一', '王五', '张三', '李四'} {'李四'} {'李四', '王五', '张三'} set() 函数 3.3.9函数 关于函数的讲解视频可扫描二维码观看。 函数是组织好的、可重复使用的、用来实现单一或相关联功能的代码段。函数能提高模块的应用和代码的重复利用率。Python提供了许多内建函数,如print()。用户也可以自己创建函数,这样的函数被称为用户自定义函数。 用户定义一个自己想要功能的函数时,需要遵循下列规则。 (1) 函数代码块以def关键词开头,后接函数标识符名称和圆括号。 (2) 任何传入的参数和自变量必须放在圆括号中间,圆括号之间可以定义参数。 (3) 函数内容以冒号起始,并且缩进。 (4) return[表达式]结束函数,选择性返回一个值给调用方。不带表达式的return语句相当于返回None。 (5) 方法与方法要间隔2行。 1. 函数的语法 一个函数由名字、参数和函数体3个部分组成。 Python定义函数时使用def关键字,格式如下: def 函数(参数列表): 函数体 PyCharm编译工具要求Python中的方法与方法的间隔为2行。示例代码如下: def method1(): print("无参函数") def method2(a): print("有一个参数函数,参数值为: ", a) def method3(a, b, c): print("多个参数函数,参数值为: ", a, b, c, end="\t") # 调用函数 method1() method2("Python") method3("Python", 88, "基础语言") 输出结果: 无参函数 有一个参数函数,参数值为: Python 多个参数函数,参数值为: Python 88 基础语言 2. 函数调用 定义一个函数时需要给函数一个名称,可指定函数中的接收参数和代码块结构。这个函数的基本结构完成以后,用户可以通过另一个函数调用执行,也可以直接通过Python的命令提示符执行。 示例代码如下: def method1(): print("无参函数") # 在函数中调用另一个函数 method2("测试") def method2(a): print("有一个参数函数,参数值为: ", a) # 调用函数 method1() 输出结果: 无参函数 有一个参数函数,参数值为: 测试 3. 变量 函数中的变量不能跨区域使用。如图3.29所示,在函数外调用函数内的变量时,将出现该变量的作用域错误的问题,这时a变量在方法内,称为局部变量。局部变量的作用域在该方法内。 变量定义在方法外的变量称为全局变量。全局变量在整个.py文件中均有效,如图3.30所示。 图3.29局部变量示例 图3.30全局变量示例 4. 设置默认值 函数除了定义标准的参数外还有一些特殊的传参方式,例如设置参数默认值、设置不定长参数。 可以通过设置参数默认值从而设置指定传参的默认值,没有传入该参数时,将使用它的默认值。 示例代码如下: def method(name, age=20): print(name, age) method("张三", 33) method("李四") 输出结果: 张三 33 李四 20 5. 设置不定长参数 用户如果需要使用一个函数处理更多的参数时,可将其定义为不定长参数。不定长参数允许传入多个参数,这些参数将以元组形式存在。 示例代码如下: def method(name, age=20, *score): print(name, age, score) method("张三", 33) method("李四") method("张三", 30, "A", 98.5, 10) 输出结果: 张三 33 () 李四 20 () 张三 30 ('A', 98.5, 10) 6. return语句 return语句用于结束方法或返回值。 示例代码如下: def method(): for val in range(5): if val == 3: print("结束整个方法") return else: print("打印值: ", val) method() def method2(a, b): return a + b print("返回结果值: ", method2(10, 20)) 输出结果: 打印值: 0 打印值: 1 打印值: 2 结束整个方法 返回结果值: 30 模块 3.3.10模块 关于模块的讲解视频可扫描二维码观看。 Python的流行主要得益于其有众多功能强大的库,Python自带的标准库(standard library)可以满足大多数用户的基本需求。除了函数库以外,模块(module)和包(package)也常被提及。 Python可以把定义的所有方法和变量存放在文件中,为一些脚本或者交互式的解释器实例所使用,这个文件被称为模块。 模块包含所有被定义的函数和变量的文件,其扩展名是.py。 模块可以被其他程序引入,以使用该模块中的函数等功能。引入模块有以下两种方法: (1) import 包.模块。 (2) form 包 import 模块。 1. 使用模块 以下例子使用Python标准库中的sys模块,结果如图3.31所示。 test.py import sys print("输入的结果: ") for i in sys.argv: print(i) 图3.31sys模块 上述代码中import sys引入Python标准库中的sys模块。sys.argv用于查询当前文件在本地的位置。 2. import语句 要使用Python源文件,只需要在另一个源文件中执行import语句即可。语法如下所示。 import module1[,module2[,… moduleN] 其中,import关键字表示导入指定模块文件,当解释器遇到import语句后, 解释器会首先执行import后面指定的模块文件,并为该模块文件分配一个命名空间用于进一步使用。 3. 搜索路径 搜索路径是在Python编译或安装时确定的,搜索路径被存储在sys模块中的path变量中。 导入模块时,搜索引擎将在sys.path路径中进行搜索。如果在指定路径中搜索到要导入的包便将包导入,如果搜索不到则将会报错,如图3.32所示。 test.py import sys listVal = sys.path for val in listVal: print("搜索路径: ", val) 图3.32搜索路径 4. form…import语句 from…import语句除了导入指定模块中的单个函数外,还可以导入多个函数或全部函数。 导入多个函数的示例代码如下: test.py from db.student import study, sleep print(study("李四")) print(sleep("张三")) 导入全部函数的示例代码如下: test.py from db.student import * print(student("李四")) print(student("张三")) 5. name属性 name是一个变量,前后加两个下画线是因为这是系统定义的名字(普通变量不要使用该方式命名变量)。 name系统变量分以下两种情况。 第一种: 假如当前模块是主模块,那么此模块名字就是name,可通过if判断来执行if中的语句块,类似于Java中的main()方法。 第二种: 假如如此模块是被import导入的模块,那么此模块名字为文件名字,通过if判断就会跳过main后面的内容。 通过上面的方式,Python可以分清楚哪些是主函数,进行函数执行,并且可以调用其他模块的各个函数等。 一个模块被另一个程序第一次引入时,其主程序将运行。如果想在模块被引入时模块中的某一程序块不执行,可以用name属性使该程序块仅在该模块自身运行时执行。 test.py from db.student import * print(study("李四")) student.py def study(name): val = name + "在学习" return val def sleep(name): return name + "在睡觉" if name == "main": print(sleep("王一一")) 加上name属性后,在test.py运行时,sleep("王一一")将不会运行,只在student.py中,它才会运行。 每个模块都有一个name属性,当其值是main时,表明该模块自身在运行,否则被引入。 6. 包 包是一种管理Python模块命名空间的形式,采用“.模块名称”的形式。 在导入一个包时,Python会根据sys.path中的目录来寻找这个包中所包含的子目录。 目录只包含一个init.py的文件时才会被认作是一个包,该文件为一个空文件即可,不需要进一步操作。 用户可以每次只导入一个其中的特定模块。示例代码如下: import db.student print(db.student.study("李四")) import db.student as st print(st.study("李四")) 还有一种导入子模块的方法。示例代码如下: from db.student import study print(study("李四")) from db import student print(student.study("李四")) 类和对象 3.3.11类和对象 关于类和对象的讲解视频可扫描二维码观看。 Python设计之初就是一种面向对象的语言。正因如此,在Python中创建一个类和对象十分容易。 在计算机的世界中,对象是一个十分重要的概念。对象是程序组织代码的方法,它可以将复杂的想法拆分开,使其变得容易被理解。 在Python中,对象是由类定义的,可以把类当成一种把对象分组归类的方法。Python中的类提供了面向对象编程的所有基本功能: 类的继承、封装和多态。 案例: 通过一个人要开车从A点到B点比较面向对象与面向过程的区别。 面向过程方式如图3.33所示。 图3.33面向过程方式 面向对象方式如图3.34所示。 图3.34面向对象方式 1. 类与对象 在Java的世界中,万物皆对象,对象是类的一个实例,它有状态和行为。 类是一个模板,它描述一类对象的行为和状态,对象是具体的事物; 类是对于对象的抽象; 类可以看成一类对象的模板,对象可以看成该类的一个具体实例; 类是用于描述同一类型对象的一个抽象概念,类则是定义了这一类对象所应具有的共同属性和方法。 例如,一条狗是一个对象。它的属性为颜色、名字、品种,行为为叫、吃、跑、摇尾巴。 类与对象的关系示例如图3.35所示。 图3.35类与对象的关系示例图 2. 面向对象的特性 对象是模拟真实世界,对数据和程序进行封装。 对象 = 属性 + 方法 需要用类来创建一个对象,就像要用图纸来造房子一样。 面向对象编程的3大特性是封装、继承、多态。 (1) 封装: 把自己的属性和行为封装起来,并提供公共接口给调用者使用。 (2) 继承: 子类对父类的继承,子类拥有父类的属性和行为。 (3) 多态: 父类在子类中的多种形态。 3. 类的定义 类是一个独立存储属性和方法的空间,可使用运算符“.”来调用类的属性和方法。 示例代码如下: class Person: name = "张三" sex = "女" age = 20 def eat(self): print(self.name, "在吃饭") # 调用类 a = Person() print(a.name) a.eta() 输出结果: 张三 张三在吃饭 封装 3.3.12封装 关于封装的讲解视频可扫描二维码观看。 面向对象编程的一个重要特征就是数据封装。封装是把内部细节私有化,通过公共接口把入口和出口暴露出去来实现封装效果。 示例代码如下: class Person: name = "张三" age = 18 # 封装细节的方法 def privateMethod(self): return [self.name, self.age] # 暴露给调用者 def method(self): return self.privateMethod() p = Person() print(p.method()) 输出结果: ['张三',18] 1. 私有属性 Python默认的方法和成员变量都是公开的,Python的私有属性和方法并没有像其他语言一样用public、private等关键词来修饰。 不加任何下画线表示公开变量,它的作用域在整个项目中均有效,例如,x =“变量”。 双下画线()表示私有变量,只有内部可以访问,外部不可以访问,例如,xx =“私有变量”。 示例代码如下: class Person: name = "张三"# 公开属性 age = 18# 私有属性 p = Person() print("公开属性类外可以调用: ", p.name) print("私有属性类外不可以调用: ", p.age) 输出结果: 公开属性类外可以调用: 张三 Traceback (most recent call last): File "D:/Users/Python/PythonSpark/Test.py", line 8, in print("私有属性类外不可以调用: ", p.age) AttributeError: 'Person' object has no attribute 'age' 注意,当使用PyCharm进行Python开发时,如果需要在类中定义方法,若该方法不涉及对属性的操作,那么PyCharm会提示Method xxx may be 'static'。因为PyCharm会认为该方法是一个静态方法,而不是类方法,所以提示在该方法前添加@staticmethod装饰器进行装饰。 2. self self代表类的实例。类的方法与普通的函数只有一个特殊的区别,它们必须有一个额外的第一个参数名称,按照惯例它的名称是self。 示例代码如下: class Test: def prt(self): print(self) t = Test() t.prt() t2 = Test() t2.prt() 输入结果: 从执行结果可以很明显地看出,self代表的是类的实例,代表当前对象的地址。 构造函数 3.3.13构造函数 关于构造函数的讲解视频可扫描二维码观看。 构造函数也称为构造器,是创建对象时会被自动调用的。系统默认将提供一个无参的构造函数。 因为类可以起到模板的作用,所以在创建实例时,可以把一些自认为必须绑定的属性强制写进去。通过定义一个特殊的init()方法,在创建实例时,对属性进行赋值,称为初始化。 构造函数有以下特点: (1) 在一个类中,只能定义一个结构函数。 (2) 重新定义结构函数时可以使用init(self,arg1,arg2,…)函数。 (3) arg1,arg2,…是传入的形参,用于初始化成员变量。 (4) 在构造函数中定义的变量为成员变量(全局变量),可以在类中任意一处使用。例如,self.name = "小猫咪"。 (5) 在对象被创建时自动调用构造函数。 1. 默认构造函数 示例代码如下: class Person: def init(self): print("无参构造函数是默认方式") # 创建对象时调用无参构造函数 Person() 输出结果: 无参构造函数是默认方式 2. 有参构造函数 示例代码如下: class Person: def init(self, name): print(f"姓名: {name}") Person("张三") 输出结果: 姓名: 张三 3. 使用结构函数中的全局变量 示例代码如下: class Person: def init(self, name): self.name = name def sleep(self): return f"{self.name}在睡觉" p = Person("张三") print(p.sleep()) 输出结果: 张三在睡觉 4. 传入不定长参数 示例代码如下: class Person: def init(self, *val): self.val = val def sleep(self): return self.val p = Person("张三", "李四", "王五") print(p.sleep()) 输出结果: ('张三', '李四', '王五') 继承 3.3.14继承 关于继承的讲解视频可扫描二维码观看。 继承指的是类与类之间的关系,用来解决代码重用问题。继承有以下特点。 (1) 定义继承可直接在类名的括号中进行,只需加上所要继承的类即可。例如: class Student(Person): (2) 在Python中被继承的类称为父类,继承的类称为子类。 (3) 在Python中允许多继承。 (4) 在继承中,子类拥有父类中的成员变量和成员函数。 (5) 如果子类中定义了与父类中相同的函数名,这种方式称为重写。 (6) 如果子类继承抽象类,抽象类中有抽象函数,则子类必须重写。 继承的示例代码如下: class Person: name = "" def eat(self): return self.name + "在吃东西" class Student(Person): def study(self): return self.name + "在学习" s = Student() s.name = "张三" print(s.eat()) print(s.study()) 输出结果: 张三在吃东西 张三在学习 1. 导入模块 import关键字可以在不同的包中导入指定模块,实现继承关系。项目结构如图3.36所示。 图3.36项目结构 示例如下: person.py class Person: def eat(self): return "吃东西" student.py import db1.person as p class Student(p.Person): name = "王一" def sleep(self): return self.name test.py from db import student a = student.Student() # 公共方法或变量可以调用 print(a.sleep()) # 调用父类中的方法 print(a.eat()) 2. 多继承 Python与Java不同,Python支持多继承,即一个类继承多个类的属性与行为。 示例代码如下: class Person: name = "" def eat(self): return self.name + "在吃东西" class Animal: def sleep(self): return "在睡觉" class Student(Person, Animal): def study(self): return self.name + "在学习" s = Student() s.name = "张三" print(s.eat()) print(s.study()) print(s.name, s.sleep()) 输出结果: 张三在吃东西 张三在学习 张三 在睡觉 3. 方法重写 如果用户的父类方法功能不能满足用户的需求,用户可以在子类中重写父类中的方法,称为方法重写。 示例代码如下: class Person: name = "" def eat(self): return self.name + "在吃东西" class Student(Person): def eat(self): return self.name + "在学校食堂里吃东西" s = Student() s.name = "张三" print(s.eat()) 输出结果: 张三在学校食堂里吃东西 4. super()函数 super()函数是用于调用父类的一个方法。 示例代码如下: class Person: name = "" def eat(self): return self.name + "在吃东西" class Student(Person): def eat(self): return self.name + "在学校食堂里吃东西" def test(self): return super().eat() s = Student() s.name = "张三" print(s.test()) 输出结果: 张三在吃东西 5. 重写构造函数 子类可以没有构造函数,此时表示子类同父类的构造函数一致。 示例代码如下: class Person: def init(self): print("父类中的构造函数") class Student(Person): pass Student() 输出结果: 父类中的构造函数 子类可以重写构造函数。示例代码如下: class Person: def init(self): print("父类中的构造函数") class Student(Person): def init(self, name): super().init() print("重写父类中的构造函数", name) Student("张三") 输出结果: 父类中的构造函数 重写父类中的构造函数 张三 异常 3.3.15异常 关于异常的讲解视频可扫描二维码观看。 Python有两种错误很容易辨认: 语法错误和异常。 语法错误或者称为解析错误,是初学者经常遇到的错误。语法错误是语法上的错误,通常表现为少冒号、关键字输错,这类错误在解析前会由解析器进行自动检查。 异常就是一个事件,该事件会在程序执行的过程中发生,并影响程序的正常执行。 例如,下例会出现多种不同的异常。 # 下标越界异常 a = (1, 2, 5) try: print(a[5]) except IndexError as e: print("下标越界", e) # 值转换错误异常 s = "3.14" try: i = int(s) except ValueError as e: print("值转换错误", e) # key值错误异常 a = {"name": "张三", "age": 20} try: print(a["name1"]) except KeyError as e: print("key值错误异常", e) # 分母为0异常 try: a = 10 b = 0 c = a / b except ZeroDivisionError as e: print("分母不能为零: ", e) 输出结果: 下标越界 tuple index out of range 值转换错误 invalid literal for int() with base 10: '3.14' key值错误异常 'name1' 分母不能为零: division by zero 1. 异常处理 异常捕捉可以使用try…except语句。 语法格式如图3.37所示。 图3.37try…except语法格式 首先,执行try子句,如果没有异常发生,则忽略except子句,try子句执行后结束程序的执行。如果在执行try子句的过程中发生异常,那么try子句余下的部分将被忽略,执行except子句中的语句。如果异常的类型和except之后的名称相符,那么对应的except子句将被执行。如果一个异常没有与任何except子句匹配,那么这个异常将会被传递到上层的try子句中。 2. 处理多个异常 一个try语句可能包含多个except子句,分别处理不同的特定的异常,最多只有一个分支会被执行。 处理程序将只针对对应的try子句中的异常进行处理,而不是其他try子句中的处理程序的异常。 示例代码如下: while True: try: x = int(input("请输入一个数字: ")) val = 10 / x print("结果: ", val) except ValueError as e: print("你输入的不是数字,错误码为: ", e) except ZeroDivisionError as e: print("分母不能为零,错误码为: ", e) 输出结果: 请输入一个数字:0 分母不能为零,错误码为: division by zero 请输入一个数字:ddf 你输入的不是数字,错误码为: invalid literal for int() with base 10: 'ddf' 请输入一个数字:0 分母不能为零,错误码为: division by zero 请输入一个数字: 3. else语句 如果没有错误发生,则可以在except语句块后面加一个else语句。当没有错误发生时,会自动执行else语句。 示例代码如下: while True: try: x = int(input("请输入一个数字: ")) val = 10 / x print("结果: ", val) except ValueError as e: print("你输入的不是数字,错误码为: ", e) except ZeroDivisionError as e: print("分母不能为零,错误码为: ", e) else: print("系统正常,没有异常") 输出结果: 请输入一个数字: 8 结果: 1.25 系统正常,没有异常 请输入一个数字: 4. finally语句 finally语句是最终语句,表示无论如何都要执行。如果加上了finally语句,不管except语句是否被执行,finally语句都将会被执行。 在try…except…finally中,finally语句可以省略,也可以加上,但只能有一个finally语句。 示例代码如下: while True: try: x = int(input("请输入一个数字: ")) val = 10 / x print("结果: ", val) except ValueError as e: print("你输入的不是数字,错误码为: ", e) except ZeroDivisionError as e: print("分母不能为零,错误码为: ", e) else: print("系统正常,没有异常") finally: print("无论如何都执行") 输出结果: 请输入一个数字: 8 结果: 1.25 系统正常,没有异常 无论如何都执行 请输入一个数字: 0 分母不能为零,错误码为: division by zero 无论如何都执行 请输入一个数字: 5. Exception异常 Python的错误其实也是类,所有的错误类型都继承自Exception,所以在使用Exception时需要注意,它不但能够捕获该类型的错误,还能把子类也“一网打尽”。 示例代码如下: while True: try: x = int(input("请输入一个数字: ")) val = 10 / x print("结果: ", val) except Exception as e: print("Exception异常: ", e) except ValueError as e: print("你输入的不是数字,错误码为: ", e) except ZeroDivisionError as e: print("分母不能为零,错误码为: ", e) else: print("系统正常,没有异常") finally: print("无论如何都执行") 输出结果: 请输入一个数字: 0 Exception异常: division by zero 无论如何都执行 请输入一个数字: dd Exception异常: invalid literal for int() with base 10: 'dd' 无论如何都执行 请输入一个数字: 上述例子中,Exception异常出现在ValueError和ZeroDivisionError异常之前。由于Exception异常是所有异常的父类,因此,在Exception异常时就会被拦截。后面的ValueError和ZeroDivisionError异常不会被执行。由于Exception异常父类的特性,在实践中,Exception异常一般用于所有异常之后,用来拦截没有考虑到位的异常,从而保证系统的安全性。 6. 抛出异常 抛出异常是指自己不处理异常,使用raise语句将异常抛出去,由调用者自己处理。Python使用raise语句抛出一个指定的异常。raise语句是唯一一个参数指定的要抛出的异常,它必须是一个异常的实例或异常类。 示例代码如下: def sex(): a = input("请输入性别: ") if a != "男" and a != "女": raise Exception("抛出异常") print(a) try: sex() except Exception as e: print("异常信息: ", e) 输出结果: 请输入性别: 公 异常信息: 抛出异常 7. 自定义异常 可以通过创建一个新的异常类从而拥有自己的异常,自定义异常类可以继承自Exception类,可以直接继承也可以间接继承。 示例代码如下: class GenderException(Exception): pass # 定义sex()函数 def sex(): a = input("请输入性别: ") if a != "男" and a != "女": raise GenderException("性别不详") print(a) try: sex() except GenderException as e: print("异常信息: ", e) 输出结果: 请输入性别: 公 异常信息: 性别不详 操作MySQL 3.3.16操作MySQL 关于操作MySQL的讲解视频可扫描二维码观看。 1. 安装连接MySQL的驱动 MySQL是最流行的关系数据库管理系统,Python连接到MySQL数据库就需要安装MySQL官方提供的mysqlconnector驱动。 mysqlconnector驱动可以通过pip命令进行安装,如图3.38所示。 图3.38安装MySQL驱动 2. 创建数据库连接 示例代码如下: import mysql.connector as my # 第一步: 建立数据库连接 mydb = my.connect( host="localhost",# 连接地址 user="root",# 用户 password="123456" # 密码 ) myCursor = mydb.cursor() # 第二步: 执行数据库操作,创建数据库 myCursor.execute("create database xuedao charset=utf8") 执行结果如图3.39所示。 3. 创建数据表 创建数据表需要使用create table语句。在创建数据表前,需要确保数据库已经存在。以下创建一个名为student的数据表。 示例代码如下: import mysql.connector as my # 第一步: 如果直接连接数据库,可以把数据库写到connect()中 mydb = my.connect( host="localhost",# 连接地址 user="root",# 用户 password="123456",# 密码 database="xuedao" ) myCursor = mydb.cursor() # 第二步: 执行数据库操作,创建数据库 myCursor.execute( create table student ( name varchar(50), sex varchar(20), age int ) ) 执行结果如图3.40所示。 图3.39创建数据库连接执行结果 图3.40创建数据表执行结果 4. 插入数据 插入数据使用insert into语句,其中%s是占位符,它与第二个参数中、元组中的元素位置匹配。 示例代码如下: import mysql.connector as my # 第一步: 如果直接连接数据库,可以把数据库写到connect()中 mydb = my.connect( host="localhost",# 连接地址 user="root",# 用户 password="123456",# 密码 database="xuedao" ) myCursor = mydb.cursor() # 第二步: 插入一条数据到数据表 sql = "insert into student values(%s, %s, %s)" dataVal = ("李四", "女", 18) myCursor.execute(sql, dataVal) # 第三步: 提交数据到数据库 mydb.commit() 执行结果如图3.41所示。 5. 批量插入数据 批量插入数据使用executemany()方法,该方法的第二个参数是一个元组列表,包含所要插入的数据。 示例代码如下: import mysql.connector as my # 第一步: 如果直接连接数据库,可以把数据库写到connect()中 mydb = my.connect( host="localhost",# 连接地址 user="root",# 用户 password="123456",# 密码 database="xuedao" ) myCursor = mydb.cursor() # 第二步: 插入一条数据到数据库 sql = "insert into student values(%s, %s, %s)" dataVal = [("张一", "女", 8), ("张二", "男", 28), ("张三", "女", 31), ("张四", "女", 22), ("张五", "男", 19),] # 第三步: 使用executemany()方法执行批量插入 myCursor.executemany(sql, dataVal) # 第四步: 提交数据到数据库 mydb.commit() 执行结果如图3.42所示。 图3.41插入数据执行结果 图3.42批量插入数据执行结果 6. 查询数据 查询数据使用select语句。 示例代码如下: import mysql.connector as my # 第一步: 如果直接连接数据库,可以把数据库写到connect()中 mydb = my.connect( host="localhost", # 连接地址 user="root",# 用户 password="123456",# 密码 database="xuedao" ) myCursor = mydb.cursor() # 第二步: 获取全部数据 sql = "select * from student" # 第三步: 使用execute()执行数据查询 myCursor.execute(sql) result = myCursor.fetchall() # 第四步: 遍历数据结果集 print("全表输出: ") for a in result: print(a[0].decode("utf-8"), a[1].decode("utf-8"), a[2]) print() # 转出指定字段 sql2 = "select name, sex from student" myCursor.execute(sql2) result2 = myCursor.fetchall() print("指定字段输出: ") for a in result2: print(a[0].decode("utf-8"), a[1].decode("utf-8")) print() # 读取第一条数据 sql3 = "select * from student" myCursor.execute(sql3) result3 = myCursor.fetchone() print(result3[0], result3[1], result3[2]) 输出结果: 全表输出: 李四 女 18 张一 女 8 张二 男 28 张三 女 31 张四 女 22 张五 男 19 指定字段输出: 李四 女 张一 女 张二 男 张三 女 张四 女 张五 男 bytearray(b'\xe6\x9d\x8e\xe5\x9b\x9b') bytearray(b'\xe5\xa5\xb3') 18 7. where语句 如果要读取指定条件的数据,可以使用where语句。 import mysql.connector as my # 第一步: 如果直接连接数据库,可以把数据库写到connect()中 mydb = my.connect( host="localhost", # 连接地址 user="root",# 用户 password="123456",# 密码 database="xuedao" ) myCursor = mydb.cursor() sql = "select * from student where name='张一'" myCursor.execute(sql) result = myCursor.fetchall() for a in result: print(a[0].decode("utf-8"), a[1].decode("utf-8"), a[2]) # 第二步: 可以使用通配符%进行模糊查询 print() sql2 = "select * from student where name like '%张%'" myCursor.execute(sql2) result2 = myCursor.fetchall() for a in result2: print(a[0].decode("utf-8"), a[1].decode("utf-8"), a[2]) 输出结果: 张一 女 8 张一 女 8 张二 男 28 张三 女 31 张四 女 22 张五 男 19 为了防止数据库查询发生SQL注入的攻击,可以使用%s占位符来转义查询的条件。 execute()执行时需要传入两个参数: 第一个是参数化的SQL语句; 第二个是对应的实际参数值。函数内部会对传入的参数值进行相应的处理,以防止SQL注入。传入一个列表之后,MySQLdb模块内部会将列表序列化成一个元组,然后调用escape()函数把注入的SQL按空格分隔后,将正确的值赋给SQL语句。 示例代码如下: import mysql.connector as my mydb = my.connect( host="localhost", # 连接地址 user="root",# 用户 password="123456",# 密码 database="xuedao" ) myCursor = mydb.cursor() sql = "select * from student where name like %s" data = ("%张%", ) myCursor.execute(sql, data) result = myCursor.fetchall() for a in result: print(a[0].decode("utf-8"), a[1].decode("utf-8"), a[2]) 输出结果: 张一 女 8 张二 男 28 张三 女 31 张四 女 22 张五 男 19 8. 排序 查询结果排序可以使用order by语句,默认的排序方式为升序,关键字为asc,如果要设置降序排序,可以设置关键字desc。 示例代码如下: import mysql.connector as my # 如果直接连接数据库,可以把数据库写到connect()中 mydb = my.connect( host="localhost", # 连接地址 user="root",# 用户 password="123456",# 密码 database="xuedao" ) myCursor = mydb.cursor() sql = "select * from student order by age desc" myCursor.execute(sql) result = myCursor.fetchall() for a in result: print(a[0].decode("utf-8"), a[1].decode("utf-8"), a[2]) print() # 如果要设置查询的数据量,可以通过limit语句来指定,例如,获取student表中 # 年龄最大的3位同学的详细信息 sql2 = "select * from student order by age desc limit 3" myCursor.execute(sql2) result = myCursor.fetchall() for a in result: print(a[0].decode("utf-8"), a[1].decode("utf-8"), a[2]) 输出结果: 张三 女 31 张二 男 28 张四 女 22 张五 男 19 李四 女 18 张一 女 8 张三 女 31 张二 男 28 张四 女 22 9. 删除语句 要慎重使用删除语句。删除语句要确保指定了where条件语句,否则会导致整表的数据被删除。 为了防止数据库查询时发生SQL注入的攻击,可以使用%s占位符来转义删除语句的条件。 示例代码如下: import mysql.connector as my # 第一步: 如果直接连接数据库,可以把数据库写到connect()中 mydb = my.connect( host="localhost", # 连接地址 user="root",# 用户 password="123456",# 密码 database="xuedao" ) myCursor = mydb.cursor() sql = "delete from student where name=%s" data = ("张三",) myCursor.execute(sql, data) mydb.commit() myCursor2 = mydb.cursor() sql2 = "select * from student" myCursor2.execute(sql2) result = myCursor2.fetchall() for a in result: print(a[0].decode("utf-8"), a[1].decode("utf-8"), a[2]) 输出结果: 李四 女 18 张一 女 8 张二 男 28 张四 女 22 张五 男 19 3.4本章小结 本章讲解了Python 3简介、环境搭建,以及基础语法的讲解,帮助学习者为后续深入学习Spark生态系统打下坚实基础。 3.5课后习题 一、 填空题 1. 在Python中,布尔类型的值是和。 2. Python可以使用、和来表示字符串,引号的开始与结束必须是相同的类型。 3. 函数用于将元组或字符串转换为列表。 4. 在Python定义的6个标准类型分别是Number、String、Tuple、、和。 5. Python的基础类型可以分为和两大类。 二、 判断题 1. Python中的变量不需要声明,每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。() 2. break语句用来终止循环语句,可以使用在循环中,也可以使用在循环外。() 3. continue语句用来跳出本次循环,告诉当前循环略过当前语句,然后继续进行下一轮循环。() 4. pass语句是空语句,为了保护程序结构的完整性,在循环语句中必须要有pass语句。() 5. 在Python中,return语句用于结束当前方法和返回值。() 三、 选择题 1. ()函数可以移除字符中所有的空格。 A. lstrip()B. startwith()C. endswith()D. replace() 2. 下列选项中,()不属于Python语句。 A. passB. breakC. println() D. return 3. 已知列表x=list(range(9)),执行语句del x[:2]之后,x的值是()。 A. [1,3,5,7,9]B. [2,4,6,8] C. [2,3,4,5,6,7,8]D. [0,1,2,3,4,5,6,7,8 ] 4. 运行下列程序后,输出结果是()。 list = ["Python", "Java", "C++"] print(len(list)) A. 1B. 2C. 3D. 13 5. 下列选项中,属于不可变类型的是()。 A. str="Python"B. list=["Python","Java"] C. dict={"name":"Python"}D. set={"Java","Python","Scala"} 四、 编程题 1. 自定义函数计算三角形面积,将计算结果返回给调用者。 2. 利用函数编写计算方法,要求任意输入一个数(x)和步长(l),判断0到x之间步长为l的所有数之和,并返回给调用者。 3. 如果有一组学生考试成绩数据,编写程序筛选出每位学生的成绩等级(筛选规则: 学习成绩大于或等于90分的同学用A表示,60~89分的用B表示,60分以下的用C表示)。 4. 一个球从100米高度自由落下,每次落地后会反跳回原高度的一半再落下,求它从开始下落到第10次落地时,共经过多少米。 3.6实训 1. 实训目的 掌握Python语言的基础语法。 2. 实训任务 利用Python语言编写基于控制台的商品购物系统,要求该系统包括商品插入、商品查询和商品筛选等模块,并提供安全退出系统的机制,系统运行效果如图3.43所示。 图3.43系统运行效果 3. 实训步骤 (1)创建数据模型。 在MySQL数据库中创建xuedao数据库,设置编码集为UTF8,如图3.44所示。 图3.44xuedao数据库 在xuedao数据库中创建commodity表,表结构如图3.45所示。 图3.45commodity表的结构 往commodity表中随意插入一些数据用于数据测试,如图3.46所示。 图3.46测试数据 (2) 在PyCharm开发工具中创建项目,并在项目中创建commodity.py文件,在commodity.py文件中编写业务逻辑,具体代码如下所示。 import mysql.connector as my class Goods: # 查询所有商品 def query(self): mydb = my.connect( host="localhost", user="root", password="123456", database="xuedao" ) mc = mydb.cursor() sql = "select * from commodity" mc.execute(sql) result = mc.fetchall() print("有以下商品: ") for a in result: print(a) mydb.close() # 根据类型查询商品 def typeQuery(self): mydb = my.connect( host="localhost", user="root", password="123456", database="xuedao" ) mc = mydb.cursor() sql = "select * from commodity where type = %s" print("请输入查询的类型: ") t = input() dataVal = (t,) mc.execute(sql, dataVal) result = mc.fetchall() print("查询结果: ") for a in result: print(a) mydb.close() # 插入商品 def insert(self): mydb = my.connect( host="localhost", user="root", password="123456", database="xuedao" ) mc = mydb.cursor() sql = "insert into commodity values(%s, %s, %s, %s)" print("请输入商品名称(字符串类型): ") n = input() print("请输入商品类型(字符串类型): ") t = input() print("请输入商品价格(数值类型): ") p = input() price = float(p) print("请输入商品产地(字符串类型): ") m = input() dataVal = (n, t, price, m) mc.execute(sql, dataVal) mydb.commit() mydb.close() # 程序主入口 if name == 'main': print("欢迎使用购物系统: ") g = Goods() flag = True while flag: print("请输入你的选择(1:插入商品 2:所有商品 3:筛选 0:退出): ") i = input() if i == "1": print("请根据提示插入商品信息!") try: g.insert() except Exception as e: print("插入失败!") elif i == "2": g.query() elif i == "3": print("请根据提示输入查询的商品类型!") g.typeQuery() elif i == "0": flag = False print("退出购买系统,欢迎下次使用") else: print("没有该选项,请重新输入!")