1 line
251 KiB
JSON
1 line
251 KiB
JSON
{"./":{"url":"./","title":"Python3小白课 介绍","keywords":"","body":"python3小白课笔记 作者:雪山凌狐 网址:雪山凌狐教程http://fox-9.com 你是否也有这样的困扰? 知识浓缩度太高,跟不上老师的节奏? 知识讲解太枯燥,认真学习几课就放弃? 专业术语太多,要记忆的太多,抓不住重点,学了就忘? 学得最快的是这部分基础课,但是最容易遗忘的也恰恰是这些基础课。 快来学习这套python3小白课吧,采用跟以往都不同的全新教学模式,历时3-5个月倾力打造的python零基础课程,特别适合python或编程零基础的学员学习,包你学完之后能够真正入门python! (说明:本套课程针对小白,对于python有一定基础,渴望掌握进阶知识的学员帮助可能不会特别大,如需要作为知识巩固的材料那也是可以的。如需要学习进阶知识,敬请关注今后会推出的进阶课程。) 学习目标 针对python零基础或编程零基础的学员,学习python3,学习编程,不再害怕并快速入门它们。 万丈高楼平地起,任何python后续的进阶学习都基于本套教程的基础,需要所有学员务必重视本套基础教程的简单学习,掌握一个基础概念,方便后续进阶拓展。 因为是系统学习,可能你在学了十来课之后常常会问到自己,我学这些个到底有什么用?能做出个什么东西来?这时候一方面心态不要着急,打好基础,之后写复杂的代码逻辑就能得心应手,想用什么就能下意识地用出来;另一方面,你可以考虑适量的进行项目驱动学习,写一点最简单的小脚本实现一个小功能,这时候会发现,提高比较快,而且基础打好会深刻的感觉到它的重要。 如果你觉得难,或者语言难,英语感到不会,怕,并没有关系,当初我在学习时,像这样的基础课程,都在跨越几年的时间里,反复学习了三四遍,因此,如果你一遍学不会,请再看一遍,直到你看懂为止即可。 课程特色 👍 针对小白同学必知必会的一些python基础知识点进行扫盲,学习完成之后,将不再惧怕编程,惧怕深入学习python其他的代码。 👍 课程注意内容的精练、简洁,不冗长拖沓,以尽可能风趣幽默但又通俗易懂的方式完成我们的学习。 👍 尽可能的在每一课将该课涉及到的一些英语单词内容教会大家。 运行环境 python3.8.2 x64(python是免费开源的) 下载:雪山凌狐教程 微信公众号 暗号:python3.8.2 IDE或编辑器选择:vscode 或 sublime 或 pycharm 均可以免费使用,任选其一即可:(课程计划使用vscode) vscode:https://code.visualstudio.com/ 微软出品,完全免费,插件丰富。下载后安装chinese扩展可以汉化,然后安装python扩展支持python。可以在程序内部调试python程序,或调起终端执行。中量级,约两百多M。 简单教学:Microsoft VS Code安装和汉化指南 sublime:http://www.sublimetext.com/ 增强型笔记本软件,插件丰富,免费使用全部功能,但在你使用约20分钟,你保存的时候会弹出让你买正版的提示,关闭即可。正版应该是99美元左右。Ctrl + B可以在软件内部编译程序调试。轻量级,约三十多M。 简单教学:Sublime刚安装怎么用?做好这几步,大刀阔斧用起来! pycharm:https://www.jetbrains.com/pycharm/download/ JetBrains大厂出品,专职用于python项目,下载免费的Community社区版学习足够。Professional专业版比较适合你写web站点的python程序使用,初级学习不需要。做大型项目更友好,重量级,约1G。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2022-09-14 17:45:31 "},"Catalog.html":{"url":"Catalog.html","title":"课程目录","keywords":"","body":"课程目录 一、Python初识 1-1 python3小白课:python语言简介 1-2 python3小白课:python下载 1-3 python3小白课:python安装 1-4 python3小白课:我的第一个python脚本 1-5 python3小白课:如何运行py文件 1-6 python3小白课:使用python IDLE 1-7 python3小白课:使用python shell 二、变量、简单类型和运算符 2-1 python3小白课:啥是变量 2-2 python3小白课:定义常量 2-3 python3小白课:注释让你事半功倍 2-4 python3小白课:数值类型之整型 2-5 python3小白课:数值类型之浮点型 2-6 python3小白课:数值类型之复数 2-7 python3小白课:字符串入门 2-8 python3小白课:字节串 2-9 python3小白课:字符串进阶 2-10 python3小白课:赋值运算符 2-11 python3小白课:算术运算符 2-12 python3小白课:索引运算符 2-13 python3小白课:比较运算符 2-14 python3小白课:身份运算符 2-15 python3小白课:逻辑运算符 2-16 python3小白课:位运算符 2-17 python3小白课:赋值运算符扩展 2-18 python3小白课:三目运算符 2-19 python3小白课:成员运算符 2-20 python3小白课:运算符优先级 三、列表、元组和字典 3-1 python3小白课:列表和元组的区别 3-2 python3小白课:列表元组入门 3-3 python3小白课:深入列表 3-4 python3小白课:字典初识 3-5 python3小白课:字典操作基础 3-6 python3小白课:字典的常用方法 四、流程控制 4-1 python3小白课:if分支结构 4-2 python3小白课:while循环结构 4-3 python3小白课:for-in循环结构 4-4 python3小白课:for表达式 五、自定义函数 5-1 python3小白课:函数是什么 5-2 python3小白课:函数入门 5-3 python3小白课:递归函数 5-4 python3小白课:关键字参数 5-5 python3小白课:参数默认值 5-6 python3小白课:参数收集 5-7 python3小白课:变量作用域 5-8 python3小白课:局部函数 六、模块和包 6-1 python3小白课:模块的导入 6-2 python3小白课:自己写模块 6-3 python3小白课:导入模块详解 6-4 python3小白课:包是什么 6-5 python3小白课:定义包 6-6 python3小白课:包成员导入 6-7 python3小白课:模块内容查看 6-8 python3小白课:解锁你心仪的三方包 6-9 python3小白课:虚拟环境介绍和安装 6-10 python3小白课:虚拟环境使用 七、类和对象 7-1 python3小白课:一节课搞懂面向对象 7-2 python3小白课:定义类和实例化对象 7-3 python3小白课:了解实例方法 7-4 python3小白课:用property函数定义属性 7-5 python3小白课:封装和隐藏 7-6 python3小白课:类的继承和多继承 7-7 python3小白课:重写父类方法和使用super函数 7-8 python3小白课:类的多态性 7-9 python3小白课:可以被枚举的类 八、异常处理机制 8-1 python3小白课:最基本的异常处理 8-2 python3小白课:多异常捕获 8-3 python3小白课:查看详细异常信息 8-4 python3小白课:异常机制中的else块 8-5 python3小白课:finally块回收资源 8-6 python3小白课:自己引发异常 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2022-09-14 18:02:54 "},"chapter1/":{"url":"chapter1/","title":"一、Python初识","keywords":"","body":"一、Python初识 本章节让我们一起走进Python的世界,一起领略这门语言的魅力吧! 学习完本章节后,相信你对于python已经有一个大概的了解了。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-05 17:24:30 "},"chapter1/1-1 python3小白课:python语言简介.html":{"url":"chapter1/1-1 python3小白课:python语言简介.html","title":"1-1 python3小白课:python语言简介","keywords":"","body":"python3小白课:python语言简介 python的起源 python起源于1989年,由龟叔Guido van Rossum发明,是一种解释型、跨平台的语言,使用它是免费的。相比其他语言而言,代码简洁简单,应用范围广,在当下十分流行,是一门十分容易入门的编程语言。不管你是什么工作岗位,如果需要学习一门大家比较认可的编程语言的话,python首当其冲受到推荐。 python版本之谜 目前最新版本是python3以上的版本。目前使用python的用户分为使用python2.7的和使用python3的。为什么会这样呢? 因为在08年的12月,龟叔发布了python3.0的版本,决定不向下兼容python2(因为python首发版本的时间较早,比如早于unicode编码标准的发布时间),在这个抛开过去包袱的层面上对该语言做了一定的改进,对我来说,最大能感受到的变化有两点,一个是print打印输出内容到控制台的一个功能,新的写法跟旧的写法是不一样的,另一个就是编码问题,这对于许多写python代码又涉及中文的朋友感受可能更多一些。在python2中,默认的代码编码是ASCII编码,这样在输出一些中文字符串的时候常常遇到乱码的问题,需要各种解码、编码、转换编码等复杂操作才能不乱码,非常烦人。而python3代码的默认编码为utf-8编码,默认就支持了中文,所以在编码这块用python3会省心许多。 还有一些其他的差异,但差异并不算很多,如果你过去学习过python2,那么python3也是很容易上手的。 [!note] python2.7是python2.x系列的最后一个会维护的版本,但官方宣布在2020年停止维护,目前看来,可能是真的要跟我们说再见了。 python2.7.18版本是目前python官方说的最后一个python2的版本,发布日期为2020年4月20日。 python2停止更新参考链接:https://pythoninsider.blogspot.com/2020/04/python-2718-last-release-of-python-2.html 学习python2还是python3? 其实在发布python3的时候,已经有非常多优秀的代码、三方库等都是用python2写的了,这时候大家的选择很多,而且很多大型公司内部都在用python2来编写一些代码做一些运维工作之类的或者其他(包括现在依然也是)。 我个人也在这个问题上纠结过无数次,那么本套教程的想法是,鉴于目前看到python2已经停止了进一步更新维护,python3才是我们应该考虑的未来。本套教程只着重讲解python3的基础内容,不对python2进行教学,如果你担心你写的代码跟公司的python2项目等不兼容的话,没有关系,我们后面讲解虚拟环境的搭建和使用,在不影响现有所有python2项目的基础上,顺利跑起来你写的python3的代码,也不是难事。 因此,我们的课程的所有内容均基于python3以上的版本学习,最好是python3.6+的版本。 python的用途 没有接触过python或者没有接触过编程的同学,一定会问出这个问题,python能做啥?能如何帮到我的工作和生活? 我们可以简单罗列一些: web开发:也就是写网站,很多知名网站用python来做为主要开发语言,咱们列举几个:豆瓣、知乎、果壳网、Google、NASA、YouTube、Facebook等等。 网络爬虫:简单来说就是数据采集,从公开的互联网的数据中抓取所需要的信息下来,可以做后续分析啊什么的。如果你学习过易语言,可以跟易语言post技术相类比,而且在某些方面比易语言要优秀。 数据分析:将大数据或普通数据进行分析等,也可以对网络爬虫爬到的数据进行分析,成熟的模块,让有些用其他语言比如matlab、R等的开发者都开始用起了python。 人工智能:目前很热门流行的一个词汇,简单来说就是通过一系列数据建立模型对计算机进行训练,让计算机在某个领域达到人一样的智能,甚至超越人类,比如模型预测、图像识别等等一些,属于目前比较前沿的科学领域了。 自动化运维:这个在一般的公司的IT部门相当常见,只需要简单的几句代码,就可以实现一些自动化运维的任务,大大节省了人工成本,同时开发难度也并不高。对于个人,一些批量性的任务,也可以自己开发个小程序来实现,从此,妈妈再也不用担心我下班晚啦。 其他:常见的比如用户界面编程(这块的话用python写界面的人不算特别多,感兴趣可以深入了解,目前个人觉得易语言写用户界面比较方便)、数据库编程(有大量数据涉及跟数据库交互的,python可以轻松解决)、游戏编程(真的,python还能写个游戏出来),还有其他的一些,咱们就不一一列举了。 总之,python能实现的东西很多,它的社区很活跃,同时,世界各地有许许多多的贡献者,还会编写自己的一些三方库(即一些已经编写好的解决方案命令,你直接调用就可以实现一些功能,不需要你自己会写)上传到python社区当中,而这些,都是免费下载和使用的。 单词释义 单词 释义 unicode 为每种语言中的每个字符设定了统一并且唯一的二进制编码,统一码、万国码、单一码 print 打印,在python中是一个像控制台输出调试内容的命令,可以理解为调试输出 ASCII 美国信息交换标准代码,共定义了128个字符,当然,没包含汉字 utf-8 8位元,是针对Unicode的一种可变长度字符编码。目前应用广泛,python3脚本的默认编码,支持中文 last 最后的 release 发行版,发布 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-08-09 09:12:04 "},"chapter1/1-2 python3小白课:python下载.html":{"url":"chapter1/1-2 python3小白课:python下载.html","title":"1-2 python3小白课:python下载","keywords":"","body":"python3小白课:python下载 官网:https://www.python.org/ 可以经过一顿操作之后找到我们需要的下载地址:(我们的课程基于win系统,下载win系统对应的版本,如果你是其他系统对应下载其他系统版本即可) python3.8.2 x64:https://www.python.org/ftp/python/3.8.2/python-3.8.2-amd64.exe 我会提供已经下载好的安装包,你可以跟着我用同一个版本学习,也可以使用自己喜欢的版本,但建议选择python3.6+的版本。 单词释义 单词 释义 executable installer 可执行安装包,你可以理解为exe文件 download 下载 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-11 21:51:16 "},"chapter1/1-3 python3小白课:python安装.html":{"url":"chapter1/1-3 python3小白课:python安装.html","title":"1-3 python3小白课:python安装","keywords":"","body":"python3小白课:python安装 安装时需要注意几个点: (1)选择好安装路径,路径中不要出现中文,尽量不要出现空格,方便后续寻址。 (2)勾选添加到环境变量,会自动添加,也可以到环境变量中自己添加一下。 单词释义 单词 释义 PATH 路径 Customize installation 自定义安装 shortcuts 快捷方式 environment variables 环境变量 location 位置,定位 Install 安装 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-11 21:51:44 "},"chapter1/1-4 python3小白课:我的第一个python脚本.html":{"url":"chapter1/1-4 python3小白课:我的第一个python脚本.html","title":"1-4 python3小白课:我的第一个python脚本","keywords":"","body":"python3小白课:我的第一个python脚本 python脚本文件是一系列python命令的集合,一般一行一条命令,它的编写很简单,普通的文本编辑器就能完成。 这里我们使用vscode软件来进行编写。 [!danger] 这里并不推荐使用记事本来编写python脚本,因为可能会有编码的问题,python3脚本默认的编码为utf-8。 这是一款十分好用轻便的代码编辑器,拥有丰富的插件和精美的代码配色,让你在编程的道路上事半功倍。 该软件是免费开源软件,大家直接下载安装使用即可。 软件的下载和使用配置请参考本笔记的首页的底部。扩展方面,安装一个python扩展即可,出品方为Microsoft,微软官方。 安装和配置完成后,我们新建一个文件,即可开始编写我们的第一个python脚本程序。 编写内容: # coding:utf-8 print(\"你好,小白同学,我是萌萌哒python~\") 保存为hello.py。 这里请注意,python脚本文件的后缀名为.py。 这样我们的第一个python脚本文件就写好啦,下节课我们来运行一下看吧! 单词释义 单词 释义 coding 代码,原型是code,ing形式 hello 你好 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-08-12 15:15:31 "},"chapter1/1-5 python3小白课:如何运行py文件.html":{"url":"chapter1/1-5 python3小白课:如何运行py文件.html","title":"1-5 python3小白课:如何运行py文件","keywords":"","body":"python3小白课:如何运行py文件 打开cmd命令提示符,输入命令: python --version [!tip] 如果报错说找不到python这个命令,那么八成是python的目录没有加入到环境变量或者环境变量没生效造成的。 如果确认没有加入,加入后重试即可。 如果是已经加入了,但还是报找不到,两个方案,一个是重启一下电脑再尝试,另一个是无需重启,使用管理员模式运行cmd窗口即可。 如果能够正确打印出版本号,则可以进入后面的操作。 找到你保存python脚本的路径,举例子,比如完整路径是D:\\scripts\\hello.py 打开cmd窗口时通常不在这个路径下。 你需要使用cd命令切换到该路径下,比如默认打开cmd的时候一般是在c盘的某个路径下,接下来你需要输入如下两个命令(输入完命令记得回车哦): cd D:\\scripts d: 这样就可以切换到d盘的该路径下了。 cd命令还可以退到上一级的目录,写法为: cd.. 进入该路径后,输入命令执行python脚本: python hello.py 一个非常简单的运行py文件的实例就完成啦!快来试试吧! 单词释义 单词 释义 scripts 脚本,复数形式 version 版本 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 16:27:48 "},"chapter1/1-6 python3小白课:使用python IDLE.html":{"url":"chapter1/1-6 python3小白课:使用python IDLE.html","title":"1-6 python3小白课:使用python IDLE","keywords":"","body":"python3小白课:使用python IDLE 如果电脑上没有安装什么文本编辑器(常见于公司服务器的场景,不太允许安装太多的三方工具软件),那么python安装后是会自带一款编辑器供你使用的,虽然我个人感觉没有其他程序写得爽,但还是得介绍让大家知道一下的,那就是python IDLE。 通过系统的搜索或者在开始菜单找到python的目录,就可以找到IDLE了,打开IDLE,可以看到默认的界面就是python shell。 python shell是一个python的行解释器,通过输入python命令,可以单行立即执行代码。有关python shell的相关内容,我们在下一节课还会做进一步讲解。 在该界面按下Ctrl+N快捷键可以新建一个python脚本文件,可以在里面编写我们的py脚本代码。编写完成并保存该文件后,可以按F5快捷键直接在该界面运行该代码。 你还可以做一些IDLE的选项和配置等的设置。 关于IDLE的知识,大家大致了解一下即可,如果你能自由安装其他软件,安装其他的编辑器或IDE都比这个强,所以大家只需要知道有这么个东西即可。 单词释义 单词 释义 IDLE 集成开发和学习环境 shell 壳,一般是命令解析器,为使用者提供命令行操作 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-08-20 13:58:36 "},"chapter1/1-7 python3小白课:使用python shell.html":{"url":"chapter1/1-7 python3小白课:使用python shell.html","title":"1-7 python3小白课:使用python shell","keywords":"","body":"python3小白课:使用python shell 上节课我们介绍过,python shell是一个python的命令行解释器,py文件可以一次性执行许多的代码,而行解释器,是输入一行代码,回车后就立即执行这一行代码,然后你可以再输入下一行。 [!question] 小白同学问:这样的话咱们执行python代码的效率岂不是很慢吗?得一行一行地执行。 其实啊,我们平常使用python shell最多的场景是临时测试某几行代码的运行效果,因为它不需要将python代码保存成文件,你可以执行任意的代码,在关闭运行窗口或退出python shell之后,它就立即丢失,不会对你造成任何的负担。你可以在里面测试任意的单条代码。 比如有时候我还拿它来当计算器使用,效果可能比系统自带的还优秀。 下面我们来介绍一下。 最常用的运行python shell的环境目前我认为是使用cmd窗口。打开cmd,输入命令python并回车,即可进入python shell,如图所示: 你可以一行行输入命令并回车,可以立即查看结果。 我还常常用它来查看某些命令自带的帮助文档(这些后续你写自己的命令的时候帮助文档也可以自己定义的),比如我想查看print命令的帮助,输入(记住命令后面不需要跟参数或者括号哦): help(print) 如果帮助文档太长显示不完,它还会在最底下显示More,继续回车即可查看剩余的帮助内容。 如果你想退出python shell,可以直接关闭cmd窗口,或者输入命令: exit() [!tip] 记住括号不要漏掉。 上述所提到的代码如下图所示: 上述就是python shell的一些基本使用,很简单,大家随便玩玩即可。 单词释义 单词 释义 help 帮助 print 打印 exit 离开,退出 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-08-20 17:43:42 "},"chapter2/":{"url":"chapter2/","title":"二、变量、简单类型和运算符","keywords":"","body":"二、变量、简单类型和运算符 本章节开始介绍一些python的基本概念、类型等,学习完本章节,你已经有了许多基础的工具可以在未来使用啦! 本章节会跟大家介绍:变量、常量、注释、数值类型、字符串、字节串、运算符等等内容。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-05 21:11:15 "},"chapter2/2-1 python3小白课:啥是变量.html":{"url":"chapter2/2-1 python3小白课:啥是变量.html","title":"2-1 python3小白课:啥是变量","keywords":"","body":"python3小白课:啥是变量 假如你是一个卖花的人,你手里有很多很多的花盆,里面带有土壤。你可以给花盆1种植玫瑰花,给花盆2种植水仙花,给花盆3种植百合花。那么比如花盆1就是变量的名,你说拿起花盆1你也就拿起了里面的玫瑰花,而玫瑰花就是变量的值。在python中,变量的值可以是各种各样的限定类型,比如可以是一个数字(数值型),也可以是一串文本内容(字符串型)。变量的名更像是一个容器,就像我们刚才比喻的花盆一样,通过名字可以跟对应的值做连接。 那么为啥我们需要用到值的时候需要含他的名字呢?一方面是因为名字更好记,另一方面也是因为它的值很多时候在代码中是可以变化的,所以叫做变量嘛。通过含名字来指代这个可能会变化的值,那么后面的代码可能就可以写得更加通用一些。 关于这一点,我们来看个小例子。 # coding: utf-8 a = 11111 b = 22222 print(a + b) 如果我们仅使用值,而不使用变量,那么我们在计算求和的时候写的是print(11111 + 22222)。这时候,如果我们需要修改11111为33333,那么我们需要改2个地方,而使用变量,则只需要在定义它的那一行修改即可。这并不是一个极端的例子,实际的代码可能有成百上千行这样的引用,使用变量,你无需记忆一长串的值的内容,而只需要记住它的名字是a和b即可,十分方便。 在python中,我们可以使用=号来做赋值运算符,它在一行代码中,可以将等于号右边的值赋值给左边。很好理解吧? 而我们需要求和呢?使用+号运算符即可。 [!tip] 我们可以用print命令将变量或表达式计算的结果打印输出在控制台上。 还有一个我们使用变量的理由,就是我们有时候无需了解中间的值是多少,只需要关心业务逻辑而已。 举个例子,比如我们需要打开一个文本文件,文件里面的全部内容我是不关心的,我要做的是想判断能否在该文件中找到某些我需要的内容罢了。 这时候我们把文件的全部内容读入了,存入变量名为aaa的变量中,此时我们无需看aaa对应的值是什么,直接对aaa变量进行寻找操作并输出查找结果即可实现我的目的。 python是一种弱类型语言 python是一种弱类型语言,体现在以下两点: (1)变量无需事先声明即可使用,比如上述例子中的变量a(没错,我们通常是这么叫的,变量a),没有声明它是什么类型,直接就可以给它赋值一个数值。 (2)变量的数据类型可以改变。比如上述例子中的变量a,现在我们的变量a是一个数值型数据,你可以在它的下面再写一行代码a = \"我是小白\",这样就可以将变量a的类型变为字符串类型了。在python中,我们使用英文的双引号或者单引号引起一段内容,表示字符串,它在你后面的学习中,还会经常碰到,后面我们还会做更加详细的讲解。 变量命名规范 在变量名起名时,我们是有一些规范的,有些变量名不支持或不合法,python的解释器就不能正常的把它当做一个变量名来来看待。 总体来说,python的变量名必须以字母、下划线_开头,后面可以跟任意数目的字母、数字和下划线_。在python中,变量起名一般不含什么中文汉字等(在python3中虽然支持中文变量名,比如语文 = 100,但不推荐,也十分罕见,因为你在敲代码的时候可能就得切换输入法了),通常都是字母、下划线的组合居多,偶尔掺杂数字。注意哦,变量名不能包含空格。 [!danger] python对大小写敏感,因此变量a和变量A是两回事。 原则上,使用简单的单词来表示这个变量的作用,或者用你能理解的写法也行,比如你也可以用拼音、或者拼音的首字母组合来作为变量名,都是可以的。 还有,一些python的保留关键字或者内置函数也不建议作为变量名使用。如果使用保留关键字做变量名,解释器会报错,如果使用内置函数名作为变量名,解释器不报错,但会把内置函数给覆盖掉,就不能使用内置函数了。 目前,python的保留关键字有如下这些: ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield'] 内置函数大概有这些: ['abs', 'all', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip'] 这些英文啥意思,咱就暂且不翻译了,用到再仔细跟大家解释。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-08-21 22:35:27 "},"chapter2/2-2 python3小白课:定义常量.html":{"url":"chapter2/2-2 python3小白课:定义常量.html","title":"2-2 python3小白课:定义常量","keywords":"","body":"python3小白课:定义常量 有了变量,让我们来讲一讲常量。 常量怎么理解?我们可以类比变量来理解,变量是可以变的量,在定义了之后,还能再次给这个变量的值重新赋值,那是变量。而常量就是在运行过程中不可变的。比如圆周率π保留两位小数是3.14,是约定俗成的不会变的东西,那我们就可以称之为常量,常量也分常量名和常量值。一般来说定义了就不会变,也不允许重新赋值。 [!note] 在很多其他的编程语言中都有常量的概念,但是在python中呢?默认是没有的。 对,你没听错,目前,python默认就不支持定义一个常量。那怎么办呢?在python的规则中,我们一般约定,当一个变量名全部大写的时候,我们就说它是一个常量(虽然这个“常量”实际上依然还可以重新被赋值)。 当然,后面改不改它,是你代码说了算的,一般我们按照约定来,不修改这种全部为大写字母的变量就可以了(数字、下划线等也可以作为“常量”的变量名的一部分)。所以,我们在定义一个变量的时候一般是要包含小写字母的。 来我们看个例子: # coding: utf-8 NAME = \"little bai\" AGE = 18 这样我们就轻松定义了两个“常量”。 延伸阅读 如果你真的想通过python定义那种不能修改的常量可以怎么做?(其实掌握课程内教学的内容已足够使用) 请看这篇文章: python中如何定义常量 python自带的常量 在python中,自带也有一小部分常量值,是不可变的,没有什么常量名常量值的说法,就是一个常量,比如布尔值,真True,假False等,它们可以直接被使用。 单词释义 单词 释义 name 姓名 little 小 age 年龄 True 真 False 假 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-08-23 20:38:22 "},"chapter2/2-3 python3小白课:注释让你事半功倍.html":{"url":"chapter2/2-3 python3小白课:注释让你事半功倍.html","title":"2-3 python3小白课:注释让你事半功倍","keywords":"","body":"python3小白课:注释让你事半功倍 [!question] 注释是啥? 大家想想,当我们在学校的时候,拿着课本,老师讲到哪里,我们是不是就在哪里做一下笔记啊?(em...要是你不做笔记,那当我没说) 这个笔记就是一种注释。 在各种编程语言中,注释是一个没什么用但又很有用的东西。它对于实际的代码用处不大,在编译或者解释代码的时候,注释内容会被自动忽略掉,实际执行时不生效。但对于我们开发者来说,堪比代码的说明文档。 因为注释内容在实际运行时会被忽略,因此你就可以理解为可以尽情恣意的在代码中编写自己喜欢的注释。 [!question] 注释写点啥呢? 嗯,原则是,你想写啥写啥,你还可以写一首诗上去呢哈哈哈。实际上,我们一般会在某几行关键代码的上方、下方、右方等位置编写注释,内容一般写的是这代码是干啥的,有什么注意事项,有什么要点,未来如何维护或者二次开发等等。 你写的越详细,对你就越有好处。 有的同学说,不用啊,不就那几行简单的代码吗?我记得住,我也都知道它干啥的,费那劲呢写注释。 实则不然。对于你自己来说,你今天记得代码是干啥的,明天记得,你能保证三四年之后你再回来看你当时写的代码是什么意思吗?当你的代码量达到成千上万行的时候,你还能清晰的知道你过去写这么多代码的逻辑结构是什么吗?有了注释,这一切就迎刃而解了。对于别人来说,当你的代码需要开源给别人看,或者进行代码团队协作,或者公司里你离职了,新同事需要维护接管你之前写的代码,没有注释,他是不是要直接去看你的代码来理解逻辑呢?因为不同的人实现同一个功能代码结构可能是有差异的,因此没有注释的代码也极其让别人痛苦,无法很好的做二次开发优化。 综上所述,注释很重要,能写的部分一定要写,首先是要满足自己知道这是干啥的,其次才是让看你代码的人也能一目了然,而且越详细的注释越有助于别人理解你的代码和你自己记忆起你的代码逻辑。有人说,合理的代码注释应该占源代码的1/3左右,这个你根据自己情况,适量就好。 [!tip] 除了添加内容注释让人明白代码是做什么的,使用注释还有一个功效,就是调试程序,比如一大段代码中,我有几行代码暂时不需要了,但是以后可能需要呀,这时候可以把这几行代码给注释掉,这样解释器在运行py脚本的时候就会忽略了,当我们再需要的时候,取消注释,就可以了。 相信大家在听完前面的内容之后都知道了注释的重要性,那么在python中,注释要怎么写呢? # coding: utf-8 \"\"\" 我是多行注释1,可以用三个双引号括起来 多行注释这是第二行 \"\"\" ''' 我是多行注释2,可以用三个单引号括起来 多行注释这是第二行 ''' # 我是单行注释,这一行的所有内容都被视为注释。 a = 1 b = 2 # 我是单行注释,#号左边是代码,右边一直到行末都是注释内容,随便写。 print(a + b) # 比如可以这样写:打印输出a与b的和 # 多行注释也可以在每一行的开头加上#号,也算多行注释的一种 # 许多文本编辑器都有自带的快捷键支持单行或多行注释或取消注释,百度或者看下编辑器的菜单栏即可 我们来看一下如上的例子,我们先来说一下后面常规的注释吧。 注释的标识符为#号,出现它,那么这一行的右侧的内容就会全部被解释器视为注释内容,在执行时会忽略不进行执行。这是一般单行注释的用法。 多行注释时,一种办法是可以通过文本编辑器的快捷键,先选中需要注释掉的多行,然后按一下快捷键,批量在前面加上#号,如果需要恢复也可以按下快捷键批量变回代码。另一种办法是使用上述代码中介绍到的多行注释的方法,使用单引号或双引号均可,效果一致,可以看你喜欢。当我们定义多行文本字符串的时候,也是用的这种方法。 咱们再来看一下开头的第一行代码,前面也有一个#号,那它是注释吗?其实也是注释的,为啥我们都需要写它呢?它的作用其实是给解释器标注脚本的编码格式,在python2中,如果不标注它,则默认代码是ascii编码的,所以需要写一下它是utf-8编码,否则解释器会报错,也不能正常处理中文。 [!tip] 在python3中,默认的脚本编码格式就是utf-8编码,因此理论上在python3中,不写它也不会报错,也能正常处理中文。但为了代码的可移植性,还是建议习惯性都写上会比较好。编码格式的定义一般写在py文件的第一或第二行。其实你就跟着我写就可以了。 关于文件编码声明的更多详细标准内容,可以查阅官方文档做延伸阅读: https://www.python.org/dev/peps/pep-0263/ Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-08-23 23:30:41 "},"chapter2/2-4 python3小白课:数值类型之整型.html":{"url":"chapter2/2-4 python3小白课:数值类型之整型.html","title":"2-4 python3小白课:数值类型之整型","keywords":"","body":"python3小白课:数值类型之整型 从这节课开始我们来介绍几种普通又常见的数据类型。 首先是数值类型,数值类型很好理解,就是用来做数学运算用的。比如我们之前课程中涉及到的人的年龄,就是一种数值。 数值类型有几种,本节课我们来讲一下——整型(int)。 整型你也可以理解为整数型,在python3中,能自动处理很大很小的整型数据,类型为int。 通常我们最常碰到的应该是十进制的数字,比如写个12,那么就是12不是别的东西。在整型中可能还能定义二进制、八进制、十六进制的表示法,但它们不常用,你也可以忽略理解它们。 来看下我们的例子: # coding: utf-8 # 定义一个整型数据 a = 1 print(a) # type命令可以查看一个值或者变量的类型,将要查看的东东括起来就可以啦~ # 命令可以嵌套,print可以把类型结果打印出来 print(type(a)) # 用0b或0B开头表示二进制整型,日常不常见 b = 0b111 print(b) # 用0o或0O开头表示八进制整型,日常不常见 c = 0o54 print(c) # 用0x或0X开头表示十六进制整型,日常不常见 d = 0x13 print(d) # python3后可以用下划线来作为整型分隔符,方便阅读,类似与会计上的,号 # 例子中其实e就是1,000,000一百万 e = 1_000_000 print(e) 从例子中我们学到了一个新的命令type()。今后如果需要查看类型的时候就可以使用它。 [!tip] 一般来讲就是用十进制就好了,其他的花里胡哨的知道下就好。 单词释义 单词 释义 int integer整数这个单词的简短形式,很多地方都能看到 type 类型 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-09-19 12:35:11 "},"chapter2/2-5 python3小白课:数值类型之浮点型.html":{"url":"chapter2/2-5 python3小白课:数值类型之浮点型.html","title":"2-5 python3小白课:数值类型之浮点型","keywords":"","body":"python3小白课:数值类型之浮点型 我们继续来讲数值类型。 浮点型(float)是另一种数据类型。 我们日常见到的小数,含有小数点的,你就可以理解为属于浮点型。 加上小数点,就会变成了浮点型。即使你写5000.0,它也是一个浮点型,请注意。 浮点型还能表示科学计数法,比如5e3表示5×103即5000。 我们来看点例子: # coding:utf-8 a = 3.14159 print(type(a)) b = 5000.0 print(type(b)) c = 5e3 print(c) print(type(c)) 大家自己在python shell里面动手试一下就好啦~ 单词释义 单词 释义 float 浮动,表示浮点型 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-08 23:49:12 "},"chapter2/2-6 python3小白课:数值类型之复数.html":{"url":"chapter2/2-6 python3小白课:数值类型之复数.html","title":"2-6 python3小白课:数值类型之复数","keywords":"","body":"python3小白课:数值类型之复数 复数(complex)其实在日常不是那么常用到,本课你可以忽略掉也可以,了解下也可以。除非你用到高精尖的数学运算逻辑。按个人经验,复数这个东西其实也基本只在学校课本中提到过了。 复数是啥?如果不是很了解的童鞋可以看一下百度百科: https://baike.baidu.com/item/%E5%A4%8D%E6%95%B0/254365?fr=aladdin 我们来看一下一个复数如何定义即可: # coding:utf-8 a = 3 + 0.2j print(a) print(type(a)) 用j或J表示虚部即可,其他为实部。 [!note] 本课不重要,理解不了可跳过。 单词释义 单词 释义 complex 复杂的,表示复数类型 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 16:58:26 "},"chapter2/2-7 python3小白课:字符串入门.html":{"url":"chapter2/2-7 python3小白课:字符串入门.html","title":"2-7 python3小白课:字符串入门","keywords":"","body":"python3小白课:字符串入门 字符串(string)这个东西我们在前面的课程中已经见过了,从本节课开始我们来系统的学习一下字符串所需掌握的一些必备知识。在日常的编程处理中,字符串的处理可以说是一个大头,所以掌握好字符串的各项知识十分重要,请大家认真学习,我已经把最精练最常见的知识内容提炼给大家,大家只需要一步步跟着学习即可。 首先,如何定义字符串(str类型),我们直接来看例子: # coding:utf-8 a = \"我是小白我很白\" b = '我是小黑我不黑' print(a) print(type(b)) 我们可以看到,使用单引号、双引号都可以定义字符串,他们并没有啥区别。 [!question] 小白问,那么为啥我们要有两种符号支持呢? 来看看下面这个场景,当我们字符串内容中含有单引号或者双引号的时候: # coding:utf-8 a = 'I'm little bai' print(a) 这时候python解释器会无法判定这个字符串的结尾在哪,是在中间还是在结尾?此时就会报错。我们可以修改成这样: # coding:utf-8 a = \"I'm little bai\" print(a) 这时候单双引号均可的好处就凸显了。 [!question] 小白又问了,那么要是字符串内容里,咱们既有单引号,又有双引号,这可咋办? 别怕,我们可以使用\\符号写在字符串内的引号前面,表示转义。通过转义,python解释器在解释的时候,就会把它当做原来的单双引号输出了。来我们看一下例子: # coding:utf-8 a = \"I'm \\\"little bai\\\"\" print(a) 多个字符串拼接 如果我们有多个字符串需要拼接,通常的做法是使用+号。 # coding:utf-8 a = \"hello\" b = \"little bai\" print(a + \" \" + b) 你看,很简单的,我们还能把空格打出来。 这里需要注意的是,加在一起的内容中,都应该是字符串,如果含有数字加在一起,会报错,正确的方式是将数字通过str命令转化成字符串后再相加。(同理,转换成整型、浮点型你也可以用int、float内置命令实现从字符串转化成数值哦) #coding: utf-8 a = \"my age is\" b = 19 print(a + \" \" + str(b)) 多行字符串 [!question] 如果我们有多行字符串内容,我们应该如何定义呢? 还记得我们学过的多行注释吗?没错,就是使用三个单引号或三个双引号来实现。在这样的定义方法中,我们不仅能保留多行之间的缩进能信息,还能省去使用转义符等内容。我们来看一下例子: # coding:utf-8 a = \"\"\" 朝辞白帝彩云间, 千里江陵一日还。 两岸猿声啼不住, 轻舟已过万重山。 I'm \"little bai\" \"\"\" print(a) 是不是很方便呢? 原始字符串 最后再来讲一个原始字符串,这个我个人的使用不是特别多,但了解下也可以的。我们前面知道,\\为转义符号,所以当我们的字符串是一个windows的文件路径的时候,它就带有\\,所以我们表示win路径的时候,通常需要这样写(一般我个人也是这么写的): # coding:utf-8 a = \"E:\\\\Programs\\\\python3小白课\\\\python3小白课笔记\" print(a) 如果不这样用,有时候在py脚本中就会给你报错。 如果你不喜欢用转义符来弄,可以用原始字符串(raw): # coding:utf-8 a = r\"E:\\Programs\\python3小白课\\python3小白课笔记\" print(a) 即前面简单加上一个r修饰字符串即可。 input函数 入了门,我们来学习一个新的内置函数:input。这个函数可以获取用户的输入内容,这个内容在python3中都会统一返回字符串(所以即使输入数字也无需转换成str类型),你可以用变量接收它的返回值并做后续处理。可以用作用户交互或者跟你自己的交互。 # coding:utf-8 a = input(\"你叫什么名字呀?\") print(\"你的名字是:\" + a) a = input(\"你多少岁呀?\") print(\"你\" + a + \"岁了\") 单词释义 单词 释义 string 字符串,短一点的写法叫做str,也是一个内置命令 my 我的 is 是 raw 原始的 input 输入 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 16:59:31 "},"chapter2/2-8 python3小白课:字节串.html":{"url":"chapter2/2-8 python3小白课:字节串.html","title":"2-8 python3小白课:字节串","keywords":"","body":"python3小白课:字节串 本节课所介绍的字节串(bytes)类型比较抽象一点,如果你无法理解掌握,可以先跳过,以后可以结合一些网上的资料再次学习。 这是python3新增的类型,byte表示字节,加个复数形式就当做串了。跟字符串类似,也是一串的内容,但是是以二进制来存储的。二进制可以用于网络传输数据,也可以存储各种二进制文件,如图片、音乐、视频、exe应用程序等。 字符串和字节串之间也可以相互转换,即把字符串弄成二进制表示了,后续更利于传输或者针对里面的内容更好的进行文本加密或解密,或编码,在这块更加方便一些。 有关字节串我们就不讲那么详细了,感兴趣的同学可以自行百度下相关知识,我们来看点简单的例子: # coding:utf-8 # 将字符串转为bytes类型,用utf8编码,不指定默认也是这个 a = b'Hello' # 这种方式只能支持仅含ascii字符的字符串,含有中文会报错 print(a) # 后面这两种方式结果一致,等效,爱用哪个用哪个 a = bytes(\"Hello 小白\", encoding='utf-8') print(a) a = \"Hello 小白\".encode('utf-8') print(a) # 将字节串解码回字符串,用utf8编码,不指定默认也是这个 b = a.decode(\"utf-8\") print(b) # 也可以这样解码,还是爱用哪个用哪个 b = bytes.decode(a, encoding=\"utf-8\") print(b) 可以注意到字节串打印输出的时候前面有一个b开头修饰,并且二进制内容在遇到非ascii字符时可能会用十六进制表示法来表示并打印出来。 单词释义 单词 释义 bytes 字节的复数形式,在python中翻译为字节串型 encoding 编码,encode的ing形式,encode为编码这个单词的原型 decode 解码 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-08 23:49:24 "},"chapter2/2-9 python3小白课:字符串进阶.html":{"url":"chapter2/2-9 python3小白课:字符串进阶.html","title":"2-9 python3小白课:字符串进阶","keywords":"","body":"python3小白课:字符串进阶 之前我们学习了python字符串的入门知识,它们内容不少,不知道大家消化得怎么样了呢? 这节课我们来学习一些字符串的进阶知识,掌握好本节课的内容,对你高效的使用字符串帮助颇大,我们依然提取最精练的内容传授给大家。 转义字符 之前我们讲解过\\符号可以作为转义字符。除了之前教学的场景之外,python还能支持一些其他的转义符,我们来列举常用的一些: # coding:utf-8 # \\n表示换行符,比较常用到 a = \"我是第一行\\n我是第二行\" print(a) # 当我们要循环打出一段字符串的时候,不需要写多遍,用*号,后面加上重复的次数即可,比如这里打印40个*号 print(\"*\" * 40) # \\t表示制表符,类似你键盘上的Tab键的距离 b = \"我是第一行\\t我是第二行\" print(b) 上面的例子包含的知识点挺多哦,好好学习下。 其他还有一些自带支持的转义符我们就不一一列举了,感兴趣的同学可以自行找下资料。 格式化字符串 还记得我们入门的时候,使用的是+号的方法把字符串联结起来,当遇到不同类型的数据的时候,我们需要把数据先转换成字符串型。这样有几点不便,其中的一点是,当字符串中的变量太多,需要写多个+号来联结,另一点是要经常关注数据类型,容易报错等。 这时候,我们更常用更常见的神器,格式化字符串,来了! 先来看下例子感受一下,我用了日常编程中更为常见的转换说明符来写: # coding:utf-8 a = \"我的名字是%s,我的年龄是%d。\\n我知道,π的值为%.2f\" % (\"小白\", 18, 3.1415926) print(a) b = \"现在你在【%s】学习python小白课呢~\" % \"雪山凌狐教程\" print(b) 来我们来看一下,这两句示例代码都先用字符串定义了一串的内容,空格之后跟了一个%符号,再空格之后,对应的写入了一些内容,有的用括号括起来了,有的没用,对吧? 那么我们首先看一下第一部分的字符串内容,通过对比输出结果,我们可以看到,我们在字符串中也有%号,并且后面跟了一些字母等内容。接下来我们就来解释一下我们用到的几个转换说明符: 转换说明符 说明 %s 将内容(变量或者表达式)用str命令转换为字符串 %d 转换为带符号的十进制形式的整数 %f 转换为十进制形式的浮点数,.num表示保留小数点后面num位,如果给的值不够这个num大,则会补位 其他一些转换说明符还有,不过掌握几个常见的日常也基本够用了,这样大家记忆起来就不费力。如果你对其他的说明符感兴趣,可以自行查阅资料。 然后接下来是一个固定的%符号作为分隔符。 最后就是我们的内容了,内容可以直接写值也可以支持变量或者表达式的形式。如果前面的字符串定义了多个,需要用逗号,隔开,并且外面套上小括号,需要注意的是,前面定义了几个,后面就给几个,不要数量不正确,否则会报错哦。如果只定义了一个,那么直接写它就可以了。将一些内容用小括号括起来,在python中叫做元组(tuple)。有关元组的知识后面我们会另外再重点讲解,你稍微知道一下即可。 怎么样?是不是很方便?+号是不是少写了很多? format函数 这也是实战中用得比较多的格式化字符串的方法,我们来看个简单的例子就懂了: # coding:utf-8 # format函数的参数中,可以带上参数名,可以不按顺序,如果不带参数名,就必须按顺序给值 a = \"我的名字是{name},我的年龄是{age}\".format(age=18, name=\"小白\") print(a) # 也可以这样写和定义 a = \"我的名字是{},我的年龄是{}\".format(\"小白\", 98) print(a) 很简单,会了吗?用上{}大括号即可。 f-string 上述的格式化方法是过去的版本python一直都有的,我们这里补充讲解一下据说是python3.6版本以上才新加的东东——f-string,让我们也来潮流一把。它可能比format函数更加顺畅哦。 f-string,亦称为格式化字符串常量(formatted string literals),是Python3.6新引入的一种字符串格式化方法,主要目的是使格式化字符串的操作更加简便。 来我们直接看例子: # coding:utf-8 name = \"小白\" age = 18 a = f\"我的名字是{name},我的年龄是{age}\" print(a) 其实在这里,大括号的作用是一个python表达式,你还可以在大括号里面写表达式的。基础使用我们就讲到这里吧,它的强大之处远远不止这些,如果你想深入了解,百度一下f-string即可得到很多你想要的答案了。 字符串索引及相关方法 很多时候,我们仅需要取出一串字符串中的某些个内容,那么如何取出呢?这里我们来介绍一下索引的概念。 比如我们定义一个最简单的字符串:a = \"hello\"。 如果你算术够好,肯定能掰出五个手指头告诉我这里有5个字母。那么我们可以给他们每个字母编制一个索引。 [!danger] 在python中,索引从0开始,务必记住!是0!不是1!很多编程语言的索引都从0开始(个别从1开始索引),这对于我们日常说一楼就是一楼的人有点难抽象出来,但定义如此,请你死记硬背好~ 所以,我们的五个字母的索引分别为:0, 1, 2, 3, 4。 我们用[]中括号表示索引,如果需要取出字母e,我们可以这样表示:print(a[1]) 我们还可以有其他写法,看例子: # coding:utf-8 a = \"hello\" # 我们有如下索引对应关系: # [h -> 0], [e -> 1], [l -> 2], [l -> 3], [o -> 4] print(a[1]) # 取出从右边开始第1个字符 print(a[-1]) # 取出索引从2到4(不含4)的字符(即索引2~3的字符),注意写冒号的话永远是包含头索引不包含尾索引 print(a[2:4]) # 取出倒数第3到倒数第1(不包含倒数第1)的字符串(不能反过来写哦) print(a[-3:-1]) # 取出索引为2之后的所有字符串 print(a[2:]) # 取出索引为1(不包含1)之前的所有字符串 print(a[:1]) # 用in运算符判断某字符串在不在原字符串里面,在返回True真,不在返回False假,这个布尔型我们之前讲过 print(\"lo\" in a) # 获取字符的总长度,可以使用len函数 print(len(a)) # 经过测试,对于中文字符串,它的数数也是按照英文字符串那样来数的,你可以自行深入测试 b = \"我是小白little bai\" print(b[1]) 字符串str类型自带的一些内置方法 字符串还有一些它内置的方法,让我们处理起字符串来可以得心应手。 我们可以通过dir(str)命令查看内置的方法有哪些,dir命令也能查看其它类的内置方法,这个大家可以自己探索下。运行后,会返回一个命令列表(list),关于列表的知识我们在后面的课程中会详细的讲解,大家稍微知道一下中括号括起来的是一个列表就可以了。 我这里运行结果如下: ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] [!note] 方法有很多,其中我们注意到有很多方法开头结尾都有__双下划线符号,这些命令为python系统定义的名字,是特殊方法专用的标识,请不要自己随意定义这类命令。 剩下的那些就是内置类方法啦,里面太多了,如果你感兴趣,可以使用我们学过的help命令来查看帮助文档哦。我们来挑一些重点的来写示例讲解: # coding:utf-8 # 大小写相关方法 a = \"my name is liTTle bai 小白\" # title方法,将每个单词首字母改为大写 print(a.title()) # lower方法,将每个字母改为小写。比如在比较文件后缀名时十分有用 print(a.lower()) # upper方法,将每个字母改为大写 print(a.upper()) # 删除空白相关方法,空格,制表符等都可以 b = \" my name is liTTle bai 小白 \" # strip方法,删除首尾的空白 print(b.strip()) # lstrip方法,删除左边left的空白 print(b.lstrip()) # rstrip方法,删除右边right的空白 print(b.rstrip()) # 补充一句,这些方法有时候是可以嵌套的,不用写多行来处理,比如先变小写再删首尾空 print(b.lower().strip()) # 查找替换相关方法 c = \"my name is little bai 小白\" # startswith方法,判断字符串是不是以传入的参数开头,会返回布尔型返回值真或假 print(c.startswith(\"my\")) # endswith方法,判断字符串是不是以传入的参数结尾,会返回布尔型返回值真或假 print(c.endswith(\"bai\")) # find方法,获取参数在字符串中出现的位置索引,没有找到返回-1 print(c.find(\"is\")) # replace方法,将字符串中的某些内容(如有),替换成别的内容 print(c.replace(\"小白\", \"小黑\")) # 分割、连接方法 # split方法,将字符串按照指定的分割符分割文本,默认分割符(如果不写)为空格(可以是多个空格) d = \"my name is liTTle bai 小白\" # 出来的结果是一个列表list,后面我们可以再做详细讲解如何后续处理 print(d.split()) # join方法,刚才分割的反向操作,把一个列表的每个元素(列表中逗号分隔开的一个个称作元素) # 按照指定的连接符(比如点号.)连接起来 print(\".\".join(d.split())) 说了这么多,可能大家都已经有些晕晕乎乎的了。不过没关系,本节课值得大家细细品味,如果一遍没有掌握,请多回来看几遍,记住常用的那些命令的单词,当你需要的时候就很容易了,它们的使用都是相当简单的。 单词释义 单词 释义 Tab 这里指键盘上的Tab键,会输出一个制表符\\t num number数字的简写 tuple 元组 format 格式化 formatted string literals 格式化字符串常量 dir 全称为directory,你可以理解为目录,罗列出来 list 列表 in 在...里面 len length长度的简洁写法,这里是一个命令名 title 标题,这里是一个命令名 lower 下面的 upper 上面的 strip 除去,剥去 lstrip 应该是left strip的简写,left为左边 rstrip 应该是right strip的简写,right为右边 startswith start开始,with结合上下文理解为跟着啥 endswith end结束,with结合上下文理解为跟着啥 find 寻找 replace 替换 split 分割,分裂 join 连接,加入 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-09-19 12:35:13 "},"chapter2/2-10 python3小白课:赋值运算符.html":{"url":"chapter2/2-10 python3小白课:赋值运算符.html","title":"2-10 python3小白课:赋值运算符","keywords":"","body":"python3小白课:赋值运算符 从这节课开始我们来学习一下python中的各种运算符,说到运算符,如果你没有学习过编程的话,可能首先会想到我们数学计算中的+, -, ×, ÷几个符号吧。其实在编程语言中还有许多其他的运算符,在python中,我们大致可以分成如下几种: 赋值运算符 算术运算符 索引运算符 比较运算符 身份运算符 逻辑运算符 位运算符 三目运算符 成员运算符 本节课我们先来学习一下赋值运算符。 这个运算符,相信大家在前面的课程中已经耳熟能详了,就是一个=号。 通过它,可以将等式右边的值赋值给左边,左边可以是一个变量名来接收。 我们来直接看点例子: # coding:utf-8 # 最常见的赋值方式,右边赋值给左边 a = 1 print(a) # 变量可以赋值给变量 b = a print(b) # 表达式结果可以赋值给左边 c = b + 10 print(c) # python还能支持连续赋值,如下,d,e,f的值都被赋值为8 d = e = f = 8 \"\"\" 这里有个附加知识点: 大家看我这里写的print函数传入了众多的参数。 首先是前面几个,在python3中,print函数是支持同时打印出许多个变量的,他们可以有不同的类型 然后是后面的一些参数: sep,表示同时打印出多个变量之间的分隔符,默认是一个空格,我这里指定一个|符号分隔 end,表示打印完所有变量后的结束符,默认为\\n也就是一个换行符,我这里可以指定一些别的内容 这俩参数在某些场景下可能会用到,但不常用,大家需要时会用即可 \"\"\" print(d, e, f, sep=\"|\", end=\" 这是结束标识符\") # python还支持便捷的变量值交换 a = 1 b = 2 # 这里将变量b的值赋值给a,将变量a的值赋值给b,实现变量交换 a, b = b, a print(a) print(b) 赋值运算符,很简单。大家必须熟练掌握。 单词释义 单词 释义 sep 应为seperate分隔,分开这个单词的简写 end 结束,表示结束符 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-09 22:34:38 "},"chapter2/2-11 python3小白课:算术运算符.html":{"url":"chapter2/2-11 python3小白课:算术运算符.html","title":"2-11 python3小白课:算术运算符","keywords":"","body":"python3小白课:算术运算符 话不多说,直接看一下咱们的代码: # coding:utf-8 # +号用来算术相加,或者字符串拼接等 a = 1 + 1 b = \"little \" + \"bai\" print(a, b) # -号一般表示算术相减,或者负数等 a = 2 - 1 b = -4 print(a, b) # *号表示乘法,也可以用来重复输出字符串一定的次数 a = 8 * 3 b = \"=\" * 40 print(a, b, sep=\"\\n\") # /号表示除法,如果除不尽会出现小数,但不允许除数为0哦(除数不允许为0这个以前咱们也学过) a = 24 / 8 b = 24 / 9 print(a, b, sep=\"\\n\") # //号,表示整除,只取结果中的整数部分,小数部分不会四舍五入,而是全部舍去 a = 5 // 2 print(a) # %号表示求余运算符,需要区别我们格式化字符串的时候用%,这里是运算符,求余数 # 求余数跟整除结合,常常用来做秒跟分、小时、天等单位的换算,很有用 a = 10 % 8 print(a) # **为乘方运算符,用来求幂的,比如2的3次方就是8 a = 2 ** 3 print(a) # 当然乘方运算符还能做开方哦,比如开3次方其实就是1/3次方。经过测试我们发现返回一个float浮点数结果 a = 8 ** (1/3) print(a) 算术运算符很简单,大家请好好掌握哦。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-05 19:54:36 "},"chapter2/2-12 python3小白课:索引运算符.html":{"url":"chapter2/2-12 python3小白课:索引运算符.html","title":"2-12 python3小白课:索引运算符","keywords":"","body":"python3小白课:索引运算符 索引运算符之前我们已经遇到过了就是中括号[],通过它可以来表示索引值、索引范围等,这些我们在之前的课程中已经学习过了,所以我们就不再赘述,除了之前我们学习过的内容,索引运算符还能够指定步长,我们来看一下如下的例子: # coding:utf-8 a = \"my name is little bai\" # 取出索引1到索引10(不包含10)的内容,步长为2,也是用冒号即可 print(a[1:10:2]) Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-05 19:54:40 "},"chapter2/2-13 python3小白课:比较运算符.html":{"url":"chapter2/2-13 python3小白课:比较运算符.html","title":"2-13 python3小白课:比较运算符","keywords":"","body":"python3小白课:比较运算符 比较运算符是用来做比较的,很好理解,我们来直接看看例子再讲解: # coding:utf-8 # 比较运算符运算表达式的比较结果会返回布尔型True或者False(注意大小写),满足返回真,否则返回假 a = 10 b = 5 # 大于 print(a > 3) # 大于等于 print(a >= 10) # 小于 print(b 、!=都表示不等于,python3中不允许,所以大家统一写!=即可 print(a != 10) Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-05 19:56:50 "},"chapter2/2-14 python3小白课:身份运算符.html":{"url":"chapter2/2-14 python3小白课:身份运算符.html","title":"2-14 python3小白课:身份运算符","keywords":"","body":"python3小白课:身份运算符 身份运算符是用来表示身份的,在python中用来比较对象是否相等。返回的结果也是True或者False。 来看例子: # coding:utf-8 a = 10 b = 5 # 判断对象是否相等,常用场景是判断类型,用is关键字 print(type(a) is int) # 判断对象是否不相等,常用场景也是判断类型,判断是否是None的比较多,用is not关键字 \"\"\" None表示空值,它是一个特殊 Python 对象, None的类型是NoneType None不支持任何运算也没有任何内建方法 可以给变量赋值为None,念的时候一般称作空值或空,其他语言也有类似概念 做一些编程判断的很有用的一种类型,比如没返回任何结果可以返回None等 ***必须必须要知道它~*** \"\"\" print(type(a) is not None) c = None print(c is None) 单词释义 单词 释义 None python中的空值类型,类型名为NoneType,使用type(None)可以看到 is 是 is not is的否定形式,表示不是 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-08 23:49:45 "},"chapter2/2-15 python3小白课:逻辑运算符.html":{"url":"chapter2/2-15 python3小白课:逻辑运算符.html","title":"2-15 python3小白课:逻辑运算符","keywords":"","body":"python3小白课:逻辑运算符 逻辑运算主要用于操作布尔类型(bool)的变量、常量或表达式,逻辑运算符的返回值还是布尔类型。许多编程语言都有相类似或相同的概念,掌握一次,学习其他编程语言时即可很快上手。 python中就三个逻辑运算符,我们来直接看下代码例子: # coding:utf-8 # and,与,前后的表达式都为真时,逻辑返回结果才为真True,否则返回假False a = 10 b = 5 print(a = 100 or b == 5) # not,非,只需要一个表达式,表达式结果为True,则返回False,结果为False,则返回True,即反义 print(not(a == 10)) # 多个逻辑运算符还能嵌套运行,虽然有运算符优先级,但还是建议使用小括号把需要先算的括起来 # 这样可以保证代码的可读性,因为,一般人都记不住很多运算符的优先级的 print(a b or b == 5)) 关于逻辑运算符是大家必须掌握的东西,今后在做一些逻辑判断的时候很重要。 单词释义 单词 释义 and 与 or 或 not 非,你也可以理解为不是 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-08 23:49:48 "},"chapter2/2-16 python3小白课:位运算符.html":{"url":"chapter2/2-16 python3小白课:位运算符.html","title":"2-16 python3小白课:位运算符","keywords":"","body":"python3小白课:位运算符 位运算符是用来直接处理数字的原始bit位,是把数字看作二进制来进行计算的。常用在图形、图像处理,文本加解密等领域。 [!tip] 但在日常常见的编程中,实话说比较罕见,而且掌握起来也有一定的难度,掌握后如果不经常使用也容易忘。因此如果你没有对它的日常需要,可以不进行它的掌握,直接跳过本节即可。感兴趣的同学可以自行查阅网上的资料深入学习。 我们来看点简单的例子: 假如 a 为 60,b 为 13。则二进制格式为: a = 0011 1100 b = 0000 1101 我们有如下的运算符可供选择: 运算符 描述 实例 & 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 (a & b) 输出结果 12 ,二进制解释: 0000 1100 | 按位或运算符:只要对应的两个二进位有一个为1时,结果位就为1。 (a | b) 输出结果 61 ,二进制解释: 0011 1101 ^ 按位异或运算符:当两对应的二进位相异时,结果为1 (a ^ b) 输出结果 49 ,二进制解释: 0011 0001 ~ 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 。~x 类似于 -x-1 (~a ) 输出结果 -61 ,二进制解释: 1100 0011 左移动运算符:运算数的各二进位全部左移若干位,由 右边的数字指定了移动的位数,高位丢弃,低位补0。 a >> 右移动运算符:把>>左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数 a >> 2 输出结果 15 ,二进制解释: 0000 1111 我们来看一下验证的代码: # coding:utf-8 a = 0b00111100 # 即a = 60 b = 0b00001101 # 即b = 13 print(a, b) print(a & b) print(a | b) print(a ^ b) print(~a) print(a > 2) Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:02:09 "},"chapter2/2-17 python3小白课:赋值运算符扩展.html":{"url":"chapter2/2-17 python3小白课:赋值运算符扩展.html","title":"2-17 python3小白课:赋值运算符扩展","keywords":"","body":"python3小白课:赋值运算符扩展 通过前面的运算符学习,我们可以将赋值运算符进行一定的扩展。 比如当我们给变量自增的时候,我们可以这么写代码: a = a + 1 这么写是允许的,这样会将变量a原有的值加上1,然后再赋值回去给a。在这里,希望小白同学不要用学校里看方程一样的看法来看这个等式,问:这个怎么能相等呢?其实我们这里不是一个等式而是一种赋值形式。在编程中有很多这样的类似写法,大家需要转变一下观念。 上面的写法还有一种更优化的写法: a += 1 也能达到前面一模一样的效果,但我们敲内容已经少了很多。上述两种写法均可,这个选用哪种可以看你个人的需要,其实,哪种好理解,自己好记忆就用哪种就好了。同样的道理,大家可以举一反三,下面的代码看一下: # coding:utf-8 a = 10 print(a += 1) print(a -= 1) print(a *= 1) print(a /= 1) print(a //= 3) print(a %= 8) print(a **= 2) print(a &= 1) print(a |= 1) print(a ^= 1) print(a >= 1) Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-05 20:21:07 "},"chapter2/2-18 python3小白课:三目运算符.html":{"url":"chapter2/2-18 python3小白课:三目运算符.html","title":"2-18 python3小白课:三目运算符","keywords":"","body":"python3小白课:三目运算符 三目运算符是非此即彼的,它可以通过一行的if...else...语句来实现,if表示如果,else表示否则,如果某个表达式的值为True(相信大家看多布尔值之后也熟悉了,今后我们就尽量不在文字中说真了,尽量讲True,False同理),则返回某个结果或运行某个表达式求值,如果为False,则返回另一个结果求值。 我们来看一个简单的例子帮助大家理解: # coding:utf-8 a = \"西瓜甜\" print(\"小白吃西瓜\") if a == \"西瓜甜\" else print(\"把西瓜给小黑吃\") 其中,print(\"小白吃西瓜\")为a == \"西瓜甜\"这个表达式为True时运行的,如果它为False,则运行print(\"把西瓜给小黑吃\")后面这部分,是不是很简单呢? [!note] 三目运算符是一种简易的流程控制方式,这是我们第一次接触这样的概念,流程控制让我们的程序不再单调的只有一种可能性,而是根据实际的情况智能的返回结果。 关于流程控制的知识我们在后面的课程中还会有更加详细的讲解。 单词释义 单词 释义 if 如果 else 否则 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:02:42 "},"chapter2/2-19 python3小白课:成员运算符.html":{"url":"chapter2/2-19 python3小白课:成员运算符.html","title":"2-19 python3小白课:成员运算符","keywords":"","body":"python3小白课:成员运算符 成员运算符可以测试某个成员在不在字符串、列表、元组里面,其中列表、元组我们后面会详细讲解,本节课我们可以先接触一下。 # coding:utf-8 # 用in运算符探测成员在不在被测试者里面,前面我们也提到过不知道大家还记得不?返回布尔值结果 a = \"he\" print(a in \"hello\") # 用not in表示不在里面,不在才返回True print(a not in \"little bai\") # 也可以判断在不在列表元素中,列表用[]表示 print(1 in [1, 3, 5]) # 判断在不在元组元素中,元组用()表示 print(\"bai\" in (\"blue\", 1, 'yellow')) 单词释义 单词 释义 blue 蓝色 yellow 黄色 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-08 23:49:58 "},"chapter2/2-20 python3小白课:运算符优先级.html":{"url":"chapter2/2-20 python3小白课:运算符优先级.html","title":"2-20 python3小白课:运算符优先级","keywords":"","body":"python3小白课:运算符优先级 我们在前面的课程中学习了许许多多的运算符,我们在学习时为了简化,都是最简单的写法来表述它们,有时候一个表达式里面仅出现一个运算符,方便大家理解。而它们如果同时出现在一起,python解释器在解释的时候是有优先级顺序的,我们来看看下面的表格: Python 运算符优先级和结合性一览表 运算符说明 Python运算符 优先级 结合性 优先级顺序 小括号 ( ) 19 无 高 ︿ | | | | | | | | | | | | | | | | | | | | | | 低 索引运算符 x[i] 或 x[i1: i2 [:i3]] 18 左 属性访问 x.attribute 17 左 乘方 ** 16 左 按位取反 ~ 15 右 符号运算符 +(正号)、-(负号) 14 右 乘除 *、/、//、% 13 左 加减 +、- 12 左 位移 >>、 11 左 按位与 & 10 右 按位异或 ^ 9 左 按位或 | 8 左 比较运算符 ==、!=、>、>=、 7 左 is 运算符 is、is not 6 左 in 运算符 in、not in 5 左 逻辑非 not 4 右 逻辑与 and 3 左 逻辑或 or 2 左 逗号运算符 exp1, exp2 1 左 上面这东西,大家看一看就好,在实际编写代码的过程中,我们需要注意代码的可读性,所以我们一般不需要写那么复杂的多个运算符糅杂在一起的语句,如果有,你可以拆成多行来写,这样阅读起来更加清晰。 同时我们可以注意到优先级最高的应该是()小括号,因此我们可以完全记不住这张表,使用小括号来将表达式计算顺序来表达清楚,这样更有助于代码的可读性。 单词释义 单词 释义 atrribute 属性 exp expression表达式这个单词的简写形式 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:03:06 "},"chapter3/":{"url":"chapter3/","title":"三、列表、元组和字典","keywords":"","body":"三、列表、元组和字典 本章节我们来介绍另外几种十分常用的数据类型:列表、元组和字典。 为什么我们需要他们呢? 之前我们学习的数据类型基本上都是存储单个数据的,当我们有1~10这10个数字的时候,难道我们需要定义10个变量吗?即使定义了,你都记得住变量名吗?100个数据、1000个数据呢? 因此这样思考下来,我们之前的数据类型可能还不够,在实际编程的过程中,很大可能需要通过某个变量来批量保存大量的数据,而列表、元组和字典就能满足这样的需求。这些数据类型在我们日常的编程中也常常用到,都是必知必会的内容。 想知道它们是什么怎么用吗?快来跟我一起学习吧! Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-05 21:16:47 "},"chapter3/3-1 python3小白课:列表和元组的区别.html":{"url":"chapter3/3-1 python3小白课:列表和元组的区别.html","title":"3-1 python3小白课:列表和元组的区别","keywords":"","body":"python3小白课:列表和元组的区别 python的序列 python中可以称之为序列的有字符串、列表(list)、元组(tuple)等。它们都可以通过索引来获取其中的成员内容,比如字符串也可以打散成多个字母,对吧? 列表和元组的区别 列表和元组是一对兄弟,它们非常相像,我们来尝试定义一下: # coding:utf-8 # 定义列表 a = [1, 2, 4] # 定义元组 b = (1, 2, 4) 上述所示的代码为很简单的定义列表和元组的方法,我们可以观察到,他们的区别在于列表用的是[],而元组用的是()来定义。内部可能有许多个元素,每个元素之间使用逗号,来分隔。 [!question] 那么好像乍看起来除了用的符号框起来不一样,没啥不同呀?为什么有两种数据类型呢? 因为,列表是一种可变序列,即在定义后,你还可以往里面添加成员,减少成员等操作。但元组就不一样了,元组打从定义之后,就不允许增减,只允许读取和使用了。 所以大家应该看明白了,它们就是可变和不可变的关系。在实际编程当中,我们需要根据我们的需要来选择合适的序列使用,需要增减成员时用列表,如果确定不变的成员,并且也不允许做外部修改的的时候,用元组。 关于这两个数据类型的自带命令函数,如果不涉及成员增减的,那么它们经常都拥有这样的方法,但如果涉及成员增减的,应该说只有列表才有。从这个角度来看,你也可以认为列表是元组的增强版。 单词释义 单词 释义 list 列表 tuple 元组 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:08:09 "},"chapter3/3-2 python3小白课:列表元组入门.html":{"url":"chapter3/3-2 python3小白课:列表元组入门.html","title":"3-2 python3小白课:列表元组入门","keywords":"","body":"python3小白课:列表元组入门 上节课我们知道了列表元组之间是可变和不可变的关系,其他十分类似,因此我们在学习的时候可以一起学习进行类比。举一反三,这样大家掌握得比较快。 我们直接就着代码来进行学习吧: # coding:utf-8 # 简单定义列表、元组,里面的元素可以是各种基础的数据类型,同一个列表、元组中可以多种类型混合 a = [1, \"小白\", None] b = (1, \"小白\", None) # 除了这种定义方法,还能使用关键字命令生成列表或元组,常用来转换 aa = list(b) bb = tuple(a) print(aa, bb) print(list(), tuple(), [], ()) # 多种方法快速生成空的列表或元组 # 可以通过索引进行访问,还是用到[],跟之前字符串基本是类似的,取出来的称为子序列 print(a[0]) print(b[-2]) print(a[1:]) print(b[0:2:2]) # 列表之间、元组之间可以相加变成新序列,但不能列表+元组 print(a + [2]) # 当一个元组只有一个元素的时候,需要在结尾多写一个逗号,否则不能视为元组,这是规定:(2,) # 如果写(2),它等价于数字2,要变成元组必须加上, print((2) == 2) # 你可以这样测试 print(b + (2,)) # 列表和元组还支持乘法,可以让列表或元组重复n次 print(a * 3) print(b * 4) # 使用in运算符可以查看某元素在不在列表或元组中,这个我们已经学过 print(1 in a) print(None in b) # len函数可以查看列表或元组有多少个元素 print(len(a), len(b)) # max、min函数可以获取列表或元组中的最大或最小值,但需要元素是相同类型且可以比较大小才行 c = [3, 2, 9, 12, 30] d = (\"apple\", \"banana\", \"color\", \"zoo\") # 如果是字符串,会进行字母比较 print(max(c), min(c)) print(max(d), min(d)) \"\"\" python支持序列封包(Sequence Packing)和序列解包(Sequence Unpacking)的功能 序列封包:把多个值赋值给一个变量时,会自动将多个值封装为一个元组 序列解包:可以将列表和元组赋值给多个变量,这样元素会被依次赋值给每个变量 我们来看一下代码示例: \"\"\" # 序列封包 a = 1, 4, 8 print(a, type(a)) # 序列解包 a, b, c = [1, 2, 3] d, e, f = (4, 5, 6) print(a, b, c) print(d, e, f) # 在变量名左侧加上*号,这个变量就可以表示一个列表,支持在解包时存入列表 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 第一、第二个元素分别赋值给a1,a2,剩下的元素赋值给a3 a1, a2, *a3 = a print(a1, a2, a3, sep=\"|\") # 同理也有如下写法,啥意思呢?效果可以自行测试 a1, *a2, a3 = a print(a1, a2, a3, sep=\"|\") *a1, a2, a3 = a print(a1, a2, a3, sep=\"|\") 通过上面的学习,大家是不是对列表、元组的初步使用有了一个更深刻的认识呢?希望里面涉及的简单例子大家都自己跑一跑,保证自己能够理解和记忆。 range函数 range函数是一个生成列表很重要的函数,通常会用在for循环的流程控制当中,关于流程控制,后面的课程我们将会有更加详细的讲解。 range函数经历了一些演变,我们只需要记忆python3中的概念就好,在python3中,range函数返回一个range对象。可以被遍历(遍历的知识我们在后面再详细讲解),也可以转换成列表或者元组,这里我们来讲讲转换吧。 # coding:utf-8 # range支持1~3个参数传入,跟[]索引一样,分别表示开始、结束(不包含)、步长 # 我们可以通过list()函数转化为列表输出查看结果,如果要转成元组,使用tuple()转即可,不再赘述 print(list(range(10))) print(len(range(10))) print(list(range(1, 10))) print(list(range(1, 10, 2))) # 步长如果不传,默认为1,如果序列是逆向的,则需要传入负的步长 print(list(range(1, -10, -1))) print(list(range(1, -10, -2))) 关于range的知识,大家需要先行了解,然后熟练掌握,后续我们做循环流程控制的时候,它是一种重要的手段。 单词释义 单词 释义 list 列表 tuple 元组 apple 苹果 banana 香蕉 color 颜色 zoo 动物园 max 最大值 min 最小值 Sequence Packing 序列封包 Sequence Unpacking 序列解包 range 一系列,范围,区间,可以理解为生成区间序列 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-08 23:50:15 "},"chapter3/3-3 python3小白课:深入列表.html":{"url":"chapter3/3-3 python3小白课:深入列表.html","title":"3-3 python3小白课:深入列表","keywords":"","body":"python3小白课:深入列表 我们在前面的课程中已经初步了解了列表和元组的相关知识。 我们也知道,列表还有元组没有的增删成员等功能。因此,本节课我们再来深入了解一下列表特有的一些知识点吧。 直接上代码例子: # coding:utf-8 # 增加列表元素,最最常用。列表有点像其他编程语言中所说的数组,但它支持多种类型的元素 # 很常用的一个场景是先定义一个空列表,后续把需要存储的成员一个个存进列表去 # 使用append方法可以将元素添加到列表中,这么写: a = [] a.append(\"小白\") print(a) # 也支持增加列表、元组等等序列类型作为单个成员,可以实现列表嵌套列表或元组等的效果 a.append((1, 2, 3)) print(a, len(a)) # 如果是要追加一个列表而不是加个列表元素呢?使用extend方法 a.extend([\"apple\", \"banana\"]) print(a, len(a)) # 刚才都是添加到列表尾部的,如果希望在中间插入元素呢?使用insert方法即可,需要指定插入位置的索引 a.insert(1, \"我是插入的元素\") print(a) # 删除列表元素 # 使用del语句,可以删除列表元素、列表子序列,还能删除变量呢 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] del a[1] print(a) del a[4:] print(a) # 删除变量是del命令带的功能,删除后再打印,会报错。但我们很少做这样的操作,你可以不掌握 name = \"小白\" del name print(name) # 这句会报错 # 你还可以使用remove方法来删除元素,它不根据索引删除,根据的是元素本身删除,如果找不到会报错 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] a.remove(4) print(a) a.remove(11) # 这里找不到,会报错 print(a) # 如果你需要清空列表,将列表变回空列表,可以使用clear方法 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] a.clear() print(a) # 后面在修改元素列表的部分我们还有一种可以删除元素的方法,也是很好用的↓↓↓ # 修改列表元素 # 可以直接通过索引获取需要修改的元素来修改 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] a[1] = \"啊哦,我被修改啦~\" print(a) # 也可以通过索引的各种方法修改列表,也支持步长等修改 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 这里我们取出了两个元素,却给赋值三个元素,这样相当于删除两个,再插入三个,也是可以的 a[1:3] = [\"修改1\", \"修改2\", \"修改3\"] print(a) # 赋值为空列表,还能做到删除元素的功效,这也是一种便捷的删除元素的做法 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] a[1:3] = [] print(a) 列表的一些其他常用方法 列表还有一些其他的常用方法,如果你有需要可以使用,大致了解即可,有需要时可以查资料 # coding:utf-8 # 你可以查看有哪些内置方法,注意剔除私有方法和特殊方法 print(dir(list)) # count方法可以统计列表中某个元素出现的次数 a = [1, 2, 3, 4, 5, [5, 6, 7], 7, 8, 9, 10] print(a.count(5)) # index方法判断某个元素在列表中出现的位置,可以在第二第三个参数中指定搜索的范围,找不到会报错 print(a.index(4, 2, 3)) # pop方法可以提供元素出栈功能,实现元素的先入后出,append方法是python中的类似入栈(push)的功能 # 使用pop方法可以将列表中最后一个元素移出栈,你可以简单理解为删除最后一个元素 print(a.pop()) # 会返回那个被移出栈的元素 print(a) # reverse方法可以将元素反转,比如一堆数字,可以实现倒序排列的效果 a.reverse() print(a) # sort方法可以对元素进行排列 # 支持传入key、reverse两个参数,key参数可以指定生成比较大小的键 # reverse参数为布尔型,默认为False,从小到大排序,传入True则从大到小排列 a = [\"12345\", [5, 6, 7], \"little bai\"] # key传入len方法,注意没有括号,会计算每个元素的长度,再倒序排列,注意必须每个元素都支持len方法 a.sort(key=len, reverse=True) print(a) # 也可以做数字排序 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] a.sort(reverse=True) print(a) # 上述讲的排序方法需要改变列表本身的顺序,如果我只想排序不想改变呢? # 复制一个新列表,将新列表进行排序是一个办法,还有其他办法吗? # reversed函数可以倒序列表,生成可迭代对象,可以转化为列表展示。但不会改变原列表 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] print(list(reversed(a))) print(a) # sorted函数可以排序列表,也不会改变原列表,还支持参数 b = [2, 1, 3, 4, 5, 8, 7, 6, 9, 10] print(sorted(b)) # 这个也行,这样看来它可以替代reversed函数,但要写个参数,看个人方便吧 print(sorted(b, reverse=True)) print(b) # key参数也可以传入一个自己定义的函数,返回排序序号啥的,关于自己定义函数,我们将在后面讲到 c = [\"12345\", [5, 6, 7], \"little bai\"] print(sorted(c, reverse=True, key=len)) print(c) 单词释义 单词 释义 append 附加,增补 extend 扩展 insert 插入 del delete删除这个单词的简写 remove 拿开,去除 clear 清除,清理 count 计数 index 索引 Sequence Packing 突然地出现,突然地伸出,这是理解为出栈命令 push 推,推进去,这里理解为入栈命令,其他语言可能有push这个命令 reverse 颠倒,使反转,reversed为这个单词的过去式,意思为已反转的 sort 排序,sorted为这个单词的过去式,意思为已排序的 key 关键,钥匙,键 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-09-19 12:37:27 "},"chapter3/3-4 python3小白课:字典初识.html":{"url":"chapter3/3-4 python3小白课:字典初识.html","title":"3-4 python3小白课:字典初识","keywords":"","body":"python3小白课:字典初识 字典的引入 这节课让我们来接触一个全新的数据类型——字典(dict)。 小时候陪伴我们成长的我想肯定是一本总是被翻烂的新华字典吧。字典,存在对应映射关系,你拿着一本英汉大字典,查询某个单词,就能查到对应的释义中文解释是什么。那么在python中的字典就类似这样的映射关系。 它同样可以存储很多的数据内容,但跟我们的列表、元素不同的是,它的内部是不存在顺序的,所以我们不能使用中括号的数字索引来获取字典元素值。 为什么会有字典呢?大家可以这么想,你在查英汉字典的时候,会有如下对应关系: apple -> 苹果 banana -> 香蕉 如果我们是用列表或者元组来存储这样的对应关系,一种比较不错的方式是弄两个列表或元组,通过索引来进行一一对应。但这显然不是一种最优的方案。这时候,我们可以使用字典,字典通过键值对的方式来做一一对应的映射关系,都存在一个字典变量里面,可以达到这样的效果(注意这里不是真的python代码): a = { apple -> 苹果 banana -> 香蕉 } 这里的英文单词就是字典中的键(key),中文释义就是字典中的值(value)。它们组成key-value键值对。而且在内部没有顺序,比如你先定义banana这个键值对,跟先定义apple并没有任何区别。 [!danger] 我们可以通过键来获取值,所以在python的字典中,键不允许重复。 创建字典 [!question] 那么在python中,如何定义字典呢? 我们来看看下面的代码: # coding:utf-8 # 通过dict命令定义字典或{}定义字典,可以定义空字典 a = {} # 这种方式较常用 print(dict(), a) # 可以这么写来定义,多个字典成员之间用逗号分隔,值可以是各种基础数据类型 a = {\"语文\": 90, \"数学\": 89, \"计算机\": None} print(a) # 对于字典,python还支持跨行定义,这样看起来比较美观,实际使用时也比较推荐 a = { \"语文\": 90, \"数学\": 89, \"计算机\": 100 } print(a) # 不可变类型可以作为key,比如数字、元组等,不能是列表为key(思考为什么?)。看个例子: # 这里我们用了三种类型的数据作为键,看起来相似,但实际不同 a = { 1: 90, \"1\": 89, (1,): 100 } print(a) # python还支持通过传入列表或元组创建dict,每个元素是一个键值对,比如: a = [(\"语文\", 90), (\"数学\", 89), (\"计算机\", None)] print(dict(a)) a = [[\"语文\", 90], [\"数学\", 89], [\"计算机\", None]] print(dict(a)) # 还可以通过dict命令的关键字参数创建dict,此时关键字不用加引号,键会是字符串(大多数时候都是字符串键) a = dict(语文=90, 数学=100) print(a) # 这种方式不支持关键字用元组哦~,会报错 a = dict((1,2,3)=90, bbb=100) print(a) 单词释义 单词 释义 dict dictionary字典单词的简写形式 key 键 value 值 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:09:39 "},"chapter3/3-5 python3小白课:字典操作基础.html":{"url":"chapter3/3-5 python3小白课:字典操作基础.html","title":"3-5 python3小白课:字典操作基础","keywords":"","body":"python3小白课:字典操作基础 字典中的键(key)是字典中的关键,各种基础操作是围绕key来进行的。 我们来看一些例子代码: # coding:utf-8 # 访问字典的值,还记得列表元组使用[]加上索引来访问值吗,字典在中括号中加上键即可访问值 a = { 1: 90, \"1\": 89, (1,): 100 } print(a[(1,)]) # 我们可以随意添加不存在的键值对 a[\"语文\"] = 100 print(a) # 如果上述语句所对应的键在字典中已经存在,就能对键值对修改它的值,很方便 a[\"语文\"] = 88 print(a) # 如果要删除某个键值对,可以使用del命令,但如果该键不存在会报错 del a[\"语文\"] print(a) # 可以用in或者not in判断某个键(注意是键,不是值)在不在字典中,返回布尔值结果 print(\"语文\" in a) 字典用于格式化字符串 我们在讲字符串的章节学习过许多格式化字符串的方法,我们还记得是通过对应关系,将所需要的的值批量罗列格式化到字符串中,但这种方式只有两三个还好,如果有多个需要格式化的值内容,可能需要写很长的一串代码,有了字典,我们可以再度升华一下这种格式化的方式。 如下例子: # coding:utf-8 a = { \"语文\": 90, \"数学\": 89, \"计算机\": 100, \"英语\": 89.57 } # 还支持保留1位小数,注意这里不一定是四舍五入,比如英语成绩你设置为89.55试试? # 这是python内存储机制的原因,我们可以不深究 b = \"语文的分数是:%(语文)s,英语的分数为%(英语).1f\" % a print(b) Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-06 17:34:40 "},"chapter3/3-6 python3小白课:字典的常用方法.html":{"url":"chapter3/3-6 python3小白课:字典的常用方法.html","title":"3-6 python3小白课:字典的常用方法","keywords":"","body":"python3小白课:字典的常用方法 本节课我们来大概将一些字典自带的常用方法。 看例子: # coding:utf-8 # 查看有哪些内置方法?(注意忽略私有方法和特殊方法) print(dir(dict)) a = { 1: 90, \"1\": 89, (1,): 100, \"语文\": 90, \"数学\": 89, \"计算机\": 100, \"英语\": 89.57 } # clear,跟列表元组一样,会将字典变为空字典,copy方法可以复制一个字典副本 # 注意不要用b = a这样的写法,这样写clear b时,a也会变空字典 b = a.copy() b.clear() print(b) # get方法非常非常常用,用来取字典中某个键的值,使用[]取值如果键不存在会报错,但get方法取值不存在时, # 会返回None,或者可以指定第二个参数作为返回值。因此,实际编写中更推荐用get而弃用[],除非你百分百保证存在该键 print(a.get(\"语文\")) print(a.get(\"美术\")) # 你也可以指定返回值 print(a.get(\"美术\", 1)) # 我们需要区别于setdefault方法,这个方法可以设置一个键的默认值,当这个键找得到时,与get等效,返回值 # 但当这个键不存在时,setdefault会给字典新增这个键并赋值给的默认值,而get不会新增键 print(a.setdefault(\"美术\", 99)) # 键不存在,返回设定的第二个参数并添加键到字典中 print(a) print(a.setdefault(\"美术\", 98)) # 这次键存在,因此不会修改它的值,可以返回 print(a) # update方法可以用新字典包含的键值对来更新原有字典,当原有字典存在该键时,则更新 # 当原有字典不存在对应键时,则添加该键值对进去 a.update({\"语文\":0, \"体育\": 92}) print(a) \"\"\" 上述的一些命令是在我们知道这个字典有什么key的情况下,有的时候,我们不知道这个字典有什么键。 有什么办法能够获取键的列表以及值的列表呢? 使用items()方法可以获取字典的每个键值对,通过list命令转化成列表,每个元素是一个键值对元组。 使用keys()方法可以获取字典的每个键,通过list命令转化成列表,每个元素是一个键名。 使用values()方法可以获取字典的每个值,通过list命令转化成列表,每个元素是一个值。 ***这几个方法在做字典枚举时非常有用,请务必掌握。*** \"\"\" print(list(a.items())) print(list(a.keys())) print(list(a.values())) # pop方法用于弹出某个键值对,并删除它,找得到会返回对应的值,找不到会报错,跟列表类似 print(a.pop(\"语文\")) print(a) # popitem方法可以弹出某个键值对,实际是弹出底层存储的最后一个键值对并删除 # 由于python的字典没有顺序,我们不能说是定义的最后一个,而是底层存储的最后一个 print(a.popitem()) print(a) # 你也可以用两个变量分别接收键和值 k, v = a.popitem() print(k, v) print(a) # fromkeys方法可以批量创建指定key的字典,还能给默认值。个人很少用这个感觉 # 用列表创建,不给默认值时值默认为None a = dict.fromkeys(['a', 'b']) print(a) # 用元组创建 a = dict.fromkeys(('a', 'b')) print(a) # 指定默认值 a = dict.fromkeys(['a', 'b'], \"我是默认值\") print(a) # 如果是这样呢?会不会分别给a、b赋值默认值?请自行尝试 a = dict.fromkeys(['a', 'b'], [\"我是默认值\",\"111\"]) print(a) # 附送一个,利用字典来给列表去重的方法,尤其适用在列表元素量很大时,很方便 a = [1, 0, 3, 7, 7, 5, 5, 0, 1] newList = list({}.fromkeys(a).keys()) print(newList) 单词释义 单词 释义 clear 清除,清理 copy 复制 get 获得,得到 setdefault set设置,default默认,合起来就是设置默认值 update 更新 items 项目,一件东西(复数) keys key键的复数 values value值的赋值 pop 出栈 popitem pop item两个单词合起来,将一件东西出栈,这里是把键值对抛出字典外 fromkeys from来自...,keys,键的复数,合起来就是以很多键来怎么怎么样的意思 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-09-19 12:37:45 "},"chapter4/":{"url":"chapter4/","title":"四、流程控制","keywords":"","body":"四、流程控制 经过了前面一系列基础的学习,相信大家已经对python有了更进一步的了解,但我们之前的代码基本都是顺序执行,一写到底的。那么我们的程序就只有那么死板的一条路走到黑吗? 当然不是的,通过本章节——流程控制的学习,你会对此有一个全新的认识,通过代码的编写,你可以为你的程序注入不一样的活力,让它们像个只能机器人一样,能够智能地判断应该走哪一条路,运行哪一些代码。 越来越好玩了,不是吗? Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-06 18:44:01 "},"chapter4/4-1 python3小白课:if分支结构.html":{"url":"chapter4/4-1 python3小白课:if分支结构.html","title":"4-1 python3小白课:if分支结构","keywords":"","body":"python3小白课:if分支结构 顺序结构 当我们没有指定代码运行结构的时候,python是一条路走到黑的,即从上往下一行行解析执行代码,排在前面的先执行,排在后面的后执行。 但我们的世界都是一条路走到黑的吗? 比如小白同学很不喜欢下雨,一下雨就不想出门,那么小白同学会这么想:出门前看看外面的天气,如果是大晴天,就出门,如果下雨,就不出门。 这样的需求顺序结构就无法解决。这时候我们就需要用到if分支结构了。 if分支结构 if是如果的意思,那么它就可以用来控制我们的判断条件让程序判断一下,if语句有几种写法形式,照着小白同学的例子,我们可以写下如下的伪代码方便大家理解(注意不是真正的python代码): # coding:utf-8 # 写法1 if \"外面大晴天\": \"出门咯~\" # 写法2,else表示否则,后面不需要跟条件表达式,囊括所有其他的可能性 if \"外面大晴天\": \"出门咯~\" else: \"坚决不出门\" # 写法3,elif为else if单词的合并,表示否则如果,后面需要跟条件表达式。允许有多个elif if \"外面大晴天\": \"出门咯~\" elif \"外面大暴雨\": \"坚决不出门\" else: \"看看情况再说\" 通过上述伪代码,我们可以可以清晰的看到if分支结构的多种判断条件的写法方式以及对应怎么执行,分析上述代码,我们可以总结出if结构有如下几个写法注意点: if分支结构以if开头,后面跟随判断的条件表达式,如果表达式结果返回True,则执行if区段下面的语句,如果为False,则不执行会往下看 接下来如果有elif语句,会继续判断是否符合条件,如果为True,则执行elif下面的语句,否则继续往下 当下面再没有elif的时候,如果没有else语句,则分支运行结束,但如果有else语句,则直接运行else语句下面定义的python语句 需要注意,每个结构写完条件表达式之后的冒号:,不要漏掉了 结构下的可执行语句,大家应该很容易注意到我都是用了缩进的,这是python编程语言相比其他编程语言的一大特色(其他编程语言可能用花括号{}或者end等关键字来表示流程控制区段范围),python强制这些流程控制结构都需要采用缩进的方式来表达层级关系,比如\"出门咯~\"是缩进的,就表示它是if语句块下面要执行的分支代码,这样定义的好处是,遇到流程控制的时候,通过缩进就可以很容易区分那些是流程控制语句块下的代码,对于强迫症患者来说这是相当美观的。但它的不足之处也很明显,那就是代码编写时需要特别注意缩进,如果该缩进却没缩进,解释器是会报错的,缩进问题有时候搞疯很多人。 [!question] 那么如何缩进呢? 我个人一般使用一个Tab键的制表符距离表示缩进一层,如果层级嵌套,比如if语句可以嵌套if语句,那么就根据层级关系放适当数量的Tab距离。当然,你也可以用四个空格键来缩进(你喜欢两个空格其实也可以,但不要有时候缩进两个空格,有时候四个)。实际编写中,建议统一规范,是统一空格键还是Tab键,有时候混着用解释器也是可能报错的。一些不错的IDE可以实现一键自动帮你转换成其中一种,很少有这样的困扰,比如pycharm就能做到。 来一个嵌套的例子: # coding:utf-8 a = 10 if a >= 5: if a >= 8: print(\"大于8\") else: print(\"大于等于5小于8\") elif a [!danger] 不需要缩进的地方请不要随意缩进,比如一个顺序结构,顺着下来就行了,就没必要缩进了。 我们来看点没有好好遵循缩进原则所造成问题的例子(我们可以存到一个py文件中来运行): # coding:utf-8 a = input(\"你的语文考试多少分?\") if int(a) 上述代码执行后,如果我们输入一个90分以上的分数,则输出的结果在逻辑上是没有问题的。但当我们输入一个90分以下的分数时,print(\"哇你真棒呀,都90分以上啦!\")这句代码也被执行了,因为它没有缩进,没有在if分支结构中,是无论如何都会执行的。 if结构的判断条件 if结构后面的条件一定要是条件表达式吗?其实也不一定的,它后面的条件还能跟字符串、列表、元组、字典等等东西,这些东西也能判断出True或者False。 你需要记住的是下面这些,它们在进行if判断的时候会返回False,其他均返回True。这是if语句很容易判断返回的内容是否为空值的神器: False、 None、 0、 \"\"、 ()、 []、 {} # coding:utf-8 # 其他的类似,我们就不一一列举了,大家请自己尝试,这里拿空字符串做例子 a = \"\" if a: print(\"a不是空字符串\") else: print(\"a为空字符串\") if分支的逻辑错误 使用if分支时,有时候虽然程序不报错,但代码却犯了逻辑错误(这种错误是你的代码运行逻辑跟业务逻辑有差异,达不到你想要的效果,但在python解释器的语法上是过关的可以运行的。逻辑错误是我们编写代码的过程中比较难以发现的一种错误,因为解释器不会报错你能马上查问题,而是通过查看运行结果来分析的方式来判断我们写的是否有问题,它对于编程人员的逻辑思维、空间抽象思维的要求较高。但大家不要怕,遇到这种情况的时候,可以通过一些IDE软件的调试功能或者将逻辑抽象出来进行抽丝剥茧式的分析,是可以发现并解决问题的,相信你解决之后也会很有成就感),也就是没有达到我们要的业务效果。 我们来举个简单的例子: # coding:utf-8 score = 85 if score > 60: print(\"及格\") elif score > 80: print(\"良好\") elif score > 90: print(\"优秀\") 我们来看下上面的例子,乍看之下我们的判断条件都没有问题,60分以上的算及格,80分以上的算良好,90分以上的算优秀。那么我们的成绩score为85分,怎么也算良好这一档,对吧? 执行代码,我们发现给我们返回的结果是:\"及格\" 咦?怎么不是良好呢?其实在这里我们就犯了一个逻辑错误。85分是不是也大于60分?是的,所以在流程控制中,我们直接就从及格那里跑出来了,根本没有进行后面是否大于80分的判断。 这就是一个简单的逻辑错误,那么我们应该怎么修改呢?我们可以加上范围限制条件: # coding:utf-8 score = 85 if score > 60 and score 80 and score 90: print(\"优秀\") 通过这样的修改,我们就实现了每段判断的范围限定,就能输出良好啦。 有的同学思路很快,能想出下面更好的办法: # coding:utf-8 score = 85 if score > 90: print(\"优秀\") elif score > 80: print(\"良好\") elif score > 60: print(\"及格\") 这段代码没有添加and,只是调换了一下几个判断条件的写的顺序,也能实现我们的效果,分析一下,既然我们都是往大于的方向进行判断,那么我们应该先判断最大的,当90不满足的时候,才能判断是否大于80这一档,在判断这一档的时候,已经隐含了一个条件,那就是肯定,所以一定不可能是优秀,这时候我们就不会错漏了。 通过上述几个简单例子的学习,大家是不是对逻辑错误有了更加形象的认识?在编写代码时,我们需要多思考流程控制的最佳逻辑,这样有助于训练我们的编程逻辑思维,对大家是很有帮助的。 if表达式 之前介绍三目运算符的时候介绍过一行的if表达式写法。这里不再赘述。 当我们只有if判断想要写在一行的时候,也可以这么写: # coding:utf-8 a = 10 if a > 5 : print(\"大于5\") pass占位符 pass表示通过的意思,在python中,如果流程控制结构后面的代码执行体,我们不打算执行任何代码或者打算不进行任何代码处理,或者我们还没想好要执行啥,那么在编写时,不能够留空,会报错,这时候我们可以用pass来作为执行体的占位符,代码运行到这里就不执行任何代码往下了。 # coding:utf-8 score = 85 if score > 90: print(\"优秀\") elif score > 80: # 这里不写任何可执行的语句,可以写个pass,如果满足条件进来了,也不会执行任何东西 pass elif score > 60: print(\"及格\") 单词释义 单词 释义 if 如果 elif else if合在一起的写法,其他语言可能是用的else if这样的,python注意用elif,表示否则如果 else 否则 score 成绩 pass 通过 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:11:29 "},"chapter4/4-2 python3小白课:while循环结构.html":{"url":"chapter4/4-2 python3小白课:while循环结构.html","title":"4-2 python3小白课:while循环结构","keywords":"","body":"python3小白课:while循环结构 循环结构 除了分支结构,我们的流程控制里面还有一个大类,叫做循环结构,它是我们的程序能帮我们省去很多人力的关键。顾名思义,循环结构的作用就是能让某一段代码执行体能够反复的执行我们规定的次数,同时在执行的过程中还能有一些自己智能的选择。 我们来举个例子: 比如我们都知道,重要的事情说三次,那么我们需要实现一个功能就是设定一句话,只需要设定一次,然后就会自动说三次。如果我们打印三行相同的print代码,也是可以实现的。但如果我们说重要的事情说10遍、100遍呢?这样敲代码我们是要累死的。这时候我们就可以用上循环结构了,只需要写一行print代码,就可以实现指定次数的反复执行。 我们再来举一个例子: 比如有一个饮料自动贩售机,里面有雪碧、芬达、可乐、矿泉水四种饮品。每种饮品我们假定有5瓶,所以总共有20瓶。现在我们就来贩售饮料,它的过程是,小白同学会按下需要什么饮料,然后扫码支付对应的金额对吧,然后饮料就从贩售机下方吐出来了。这就是一个完整的售卖饮料的过程,完成之后,又会陷入等待下一位消费者购买的循环,而下一位购买者也是这样的操作步骤,只不过,有可能买的不是同一种饮料罢了。 像这样的过程,我们就完全可以使用循环结构来智能地实现。 while循环的语句结构 while循环的一般语句结构为: while 条件: 执行体 它是以while来作为关键字的,如果条件返回True,则会循环执行循环体的代码。执行完毕后,会再次判断条件是否为True,如果为False了,就会结束循环,否则再次执行循环体代码。 [!question] 有的同学会问,那什么时候是个头呢? 我们可以看到,当上述结构中的条件部分返回True时,就会执行循环体的代码。如果它一直返回为True,那么这个循环称作死循环,死循环结构在某些业务场景下也可能会写,也是允许的,比如循环监控、循环等待下一步指令等等。 但当我们只是打算循环指定的次数或者满足某些条件退出的时候,我们在写循环结构的时候,就应该注意从条件这块下功夫,当执行完执行体,条件改变之后,是可以退出循环的。所以比如我们打算实现前面的重要的话只说3遍的效果,我们可以这样写。 # coding:utf-8 a = \"我是小白,我很白,重要的话说三遍\" i = 0 while i 如代码所示,我们一般会设定一个循环变量,很多编程语言中都喜欢用i来做循环变量,当然你也可以用别的名字。设定初始值为0,条件设置为i ,每次执行完循环的执行体关键代码之后,将这个循环变量自增1。可以预见的是,i的值在循环内部会分别为0, 1, 2,当它变为3的时候,判断i 就不成立并返回False了,循环就会自动退出了,而代码正好循环了三次。 这就是我们在使用while循环时的一种通用的重复一定次数的做法。希望大家掌握它的使用。 使用while循环遍历列表或元组 使用while循环的另一种场景是遍历列表或者元组的元素,我们以列表为例子,看下怎么写: # coding:utf-8 a = [1, 2, 3, 4, 5] i = 0 while i 结合len函数还有索引访问列表成员,我们就轻松实现了列表的遍历。 while编写死循环以及break语句 我们在某些业务场景下,需要使用while死循环的,我们可以写一个永远为True的表达式,可以写while True:或者while 1==1:都行。我们看个例子: # coding:utf-8 while True: print(\"我是死循环,永远不会结束\") [!danger] 但如果你吃饱了没事儿,还是不要随便乱写,要根据自己的业务需要来编写。 如果我们编写了死循环,就永远也无法出来了吗?还是有办法的,我们可以使用break语句来实现退出当前层级的循环(注意是当前层级,比如我们在while循环里面又嵌套了一个while循环,这是两层嵌套,这时候最内层的while循环碰到了break语句,只能退出最内层循环,但还得在最外层循环中根据条件来判断是否继续循环运行。if结构不是循环结构,使用break无效)。 我们看个例子: # coding:utf-8 i = 0 while True: print(\"我是死循环,但有时候还是会无奈地结束\") i += 1 if i >= 10: break 这也是一个while结构跟if结构嵌套写的例子,大家注意看一下里面的缩进关系,编写python时缩进关系一定要注意好。这里会每次判断i的值,最后的效果是这句话只打印了10次,循环就退出了,这就是因为遇到了break语句的原因。 掌握了前面的知识,我们可以试着来写自动贩售机的源码了。大家也可以不看我写的代码,自己尝试先写一下,看能否用我们已经学过的知识写出来? 自动贩售机代码参考(我们也用上一点新知识,跟大家一同讲解提高): # coding:utf-8 # 自动贩售机源码参考 # 我们有雪碧、芬达、可乐、矿泉水四种饮品,每种饮品我们假定有5瓶 # 通过input语句获取用户需要什么饮品,可以用序号替代,买完后库存要减少 # 当需要的饮品卖完之后,会智能的弹出提示提示用户卖完了请买别的 # 定义饮品字典,通过数字序号作为key方便后续获取值 drinks = { 1: [\"雪碧\", 5], 2: [\"芬达\", 5], 3: [\"可乐\", 5], 4: [\"矿泉水\", 5] } while True: # 这里用了多行文本,多行文本内如果使用了缩进,输出时也会保留缩进,所以我们不缩进 question = f\"\"\" 你想喝什么呢? =================== 1. 雪碧(剩余{drinks[1][1]}瓶) 2. 芬达(剩余{drinks[2][1]}瓶) 3. 可乐(剩余{drinks[3][1]}瓶) 4. 矿泉水(剩余{drinks[4][1]}瓶) 请输入你想喝的饮品序号并回车: \"\"\" answer = input(question) # 字符串的isdigit方法会检查字符串是否均为数字,若是返回True if not(answer.isdigit()): print(\"\\t\\t\\t>>> 请输入饮品序号!您的输入无法识别!\") # continue可以立即结束本次循环,但还会进入下一次循环 continue answer = int(answer) if answer in range(1, 5): print(\"\\t\\t\\t>>> 您选择的饮料是:%s\" % drinks[answer][0]) if drinks[answer][1] > 0: drinks[answer][1] -= 1 print(\"\\t\\t\\t>>> 您要的饮料已弹出!\") else: print(\"\\t\\t\\t>>> 您要的饮料库存已不足!请重新选择!\") else: print(\"\\t\\t\\t>>> 啊哦,您要的饮料货架上没有,再看看吧!\") 单词释义 单词 释义 while 当...的时候 break 弄坏,弄破,这里是退出当前循环体的语句 drinks drink饮品的复数形式 question 问题 answer 答案,回答 isdigit is是,digit数字,判断是否都为数字的命令 continue 继续,python中可以立即结束当前这一次的循环 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:13:22 "},"chapter4/4-3 python3小白课:for-in循环结构.html":{"url":"chapter4/4-3 python3小白课:for-in循环结构.html","title":"4-3 python3小白课:for-in循环结构","keywords":"","body":"python3小白课:for-in循环结构 for-in循环结构 for-in循环一般用来遍历范围、列表、元组和字典等可迭代对象包含的元素。可迭代的意思是它可以多次调用获取。比如你有一个箱子,里面有40个球球,我定义,每次我喊你的名字小白同学的时候,你就会从箱子里给我拿一个球球出来,下一次喊你还是一样的拿球球。那么这个箱子就是一个可迭代对象了。 [!note] 而遍历的含义就是将所有的可能的内容都枚举出来,for-in循环更适合做这样一个事情。 for-in循环的一般语法结构为: for 循环变量 in 字符串|范围|列表元组字典等: 执行体 循环变量我们不需要自己赋值,它在进入循环的时候,就会自动从后面的字符串|范围|列表元组字典等这些可迭代对象中取出1个来,赋值给循环变量,然后进入循环。这些可迭代对象通常的理解来说是有限的,因此会循环几次基本也是可定的。在执行体的部分我们可以执行代码,下一次进入循环时还会再次执行。在执行体的部分还能访问到循环变量的值,这样就可以做一些智能化的循环操作。 for-in小例子 为了大家更快速的理解,我们还是拿之前的重要的话说三遍的例子来讲一下,之前我们是使用while循环完成的代码,这节课我们用可能更为合适这个场景的for-in循环来试一下。 # coding:utf-8 a = \"我是小白,我很白,重要的话说三遍\" for i in range(3): print(a) 我们使用了range函数来生成了一个序列,它是可迭代对象,可以直接迭代使用。可以看到,这样写,我们的代码更为简洁。 for-in遍历列表和元组和字符串 列表、元组可以直接被遍历到,我们来看下例子,这时候,循环变量代表取出来的元素,根据需要,可以做进一步判断处理: # coding:utf-8 a = [1, 2, 3] b = (1, 2, 3) for i in a: print(i) for i in b: print(i) 字符串也能被遍历,遍历出来是每个字符: # coding:utf-8 a = \"我是小白,little bai\" for i in a: print(i) 你还可以使用索引来进行遍历,是另一种比较常见的写法: # coding:utf-8 a = [1, 2, 3] b = (1, 2, 3) c = \"我是小白,little bai\" for i in range(len(a)): print(a[i]) for i in range(len(b)): print(b[i]) for i in range(len(c)): print(c[i]) for-in遍历字典 字典是键值对的形式的,但我们可以通过items()、keys()、values()这几个命令来获取字典的情况: # coding:utf-8 a = {\"语文\": 90, \"数学\": 89, \"英语\": 95} for key, value in a.items(): print(\"key: %s\" % key) print(\"value: %s\" % value) print(\"*\" * 40) for key in a.keys(): print(\"key: %s\" % key) print(\"*\" * 40) for value in a.values(): print(\"value: %s\" % value) print(\"*\" * 40) 通过字典,我们还可以统计列表中不同元素出现的次数。 # coding:utf-8 a = [1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 5, 6, 6, 4, 4, 5, 6, 7, 4] a_dict = {} for key in a: a_dict[key] = a_dict.get(key, 0) + 1 print(\"a_dict:\", a_dict) 在循环结构中使用else 循环结构也是支持else语句的,这是在python中相它编程语言一种比较特别的语法,在实际使用中,可能比较少使用吧。它使用后的逻辑为,当while或者for-in循环的循环体中没有遇到break语句强制退出时,会执行else代码段中的内容,但循环是通过break强制退出的话,那么就不会执行else代码段中的内容了。 我们来看个例子: # coding:utf-8 i = 0 while i 如果有需要,那可以考虑使用这种结构,但我个人也极少会使用到。 单词释义 单词 释义 for-in for in两个单词组成的结构,意思为对于xx在xx里面 enter 进入 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:13:59 "},"chapter4/4-4 python3小白课:for表达式.html":{"url":"chapter4/4-4 python3小白课:for表达式.html","title":"4-4 python3小白课:for表达式","keywords":"","body":"python3小白课:for表达式 for表达式基本使用 for表达式通常用于使用区间、元组、列表等可迭代对象来创建新的列表,在实战中的某些场景偶尔会用到,如果掌握比较困难,也可以不学这个。for表达式的语法如下: [表达式 for 循环变量 in 可迭代对象] for表达式只有一行,跟一般的循环结构是有点区别的,我们对比一下,它将表达式放到了for的前面,表达式部分就是我们之前讲for-in循环时的执行体部分,然后我们还注意到,外面增加了一个[],表示将生成的结果生成一个列表来包裹起来,最终返回一个列表,所以有时候我们也称之为列表推导式。 我们来看个小例子: # coding:utf-8 a = range(5) # 我们来获取一下a这个列表每个元素的平方的新列表 b = [x * x for x in a] print(b) # 我们还能添加if条件在后面,满足条件元素为偶数的才计算 b = [x * x for x in a if x % 2 == 0] print(b) [!question] 有的同学会想,如果我们将表达式的[]换成()是否可以呢?将列表换成元组,会生成一个元组吗? 我们来看一下。 # coding:utf-8 a = range(5) b = (x * x for x in a) print(b) print(type(b)) 我们会发现,返回的是一个generator对象,这个对象是一个生成器,是可以迭代的,我们可以使用for-in循环迭代。 # coding:utf-8 a = range(5) b = (x * x for x in a) for i in b: print(i) for表达式支持嵌套 for表达式也支持嵌套,两层或者三层的循环嵌套也是可以的,当然如果有if条件的需要也可以加上。 # coding:utf-8 # 我们拿稍微简单一点的两层循环嵌套来说明写法 a = [(x, y) for x in range(5) for y in range(3) if x > y] print(a) # 上述写法跟这样的写法是一样的: a = [] for x in range(5): for y in range(3): if x > y: a.append((x, y)) print(a) 看,是不是方便许多? zip压缩函数 这里我们小小的介绍一个有用的函数zip压缩函数。它可不是我们日常理解的一种压缩文件命令,而是可以将几个列表压缩成一个zip对象(可迭代对象),这样可以使用循环来并行遍历两个列表了。 我们来看个小小的例子: # coding:utf-8 a = ['a', 'b', 'c'] b = [4, 5, 6] c = [x for x in zip(a, b)] print(c) 可以看到,我们将两个列表压缩成了多个元组组合,最后再生成个列表,就是一个列表了。 如果两个列表成员数不一致会怎么样呢? # coding:utf-8 a = ['a', 'b', 'c'] b = [4, 5] c = [x for x in zip(a, b)] print(c) 可以看到效果是以短的列表为准来进行压缩。 这个函数大家知道一下即可。 单词释义 单词 释义 zip 压缩 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:14:54 "},"chapter5/":{"url":"chapter5/","title":"五、自定义函数","keywords":"","body":"五、自定义函数 恭喜你,又上了一个台阶!如今,我们可以自如地使用python的各种类型也可以使用流程控制让我们的代码更加智能了,接下来我们需要学习什么呢? 大家还记得我们之前的课程中一直在使用的python内置的一些函数、方法吗?它们是怎么来的呢?它们够用了吗?我们可不可以自己定义自己的函数、方法,实现我们自定义的需求? 本章节将带你拉开全新的大门。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-09 23:04:31 "},"chapter5/5-1 python3小白课:函数是什么.html":{"url":"chapter5/5-1 python3小白课:函数是什么.html","title":"5-1 python3小白课:函数是什么","keywords":"","body":"python3小白课:函数是什么 函数是什么 上学的时候,我相信大家学习过一种简单的函数,比如y = x + 1,通过映射关系,输入x的值,就能计算出y的值。 类似的,在编程语言中,函数可以是一段封装好的代码,你只要给它喂进去它规定需要的零到多个参数,它通过一通群魔乱舞之后就能给你吐出来结果。就像刚才说的函数等式一样,编程语言中封装的函数也能够多次进行调用。 从咱们开始学习到现在,我想使用得最多的就是内置的print函数了吧,你只需要喂给它你需要打印输出的内容,它就会输出到控制台中。同时这个命令还能无限次进行调用。 使用它的人无需在意它在内部如何群魔乱舞的细节,只需要了解它要喂什么,和它会吐什么就可以了。 但定义它的人不一样,既需要知道它需要喂什么,吐什么,还需要知道内部运行的细节,这可比仅仅使用它难多了。这跟我们制造东西一样,使用一台电脑很好学习,但制造一台电脑对个人来说可不是个容易的事情。 本章节我们主要就来讲讲定义它的一些细节。 [!note] 放心,定义函数的难易程度跟你要实现的目的有关,对于逻辑简单的函数,其实并不费什么功夫。 为啥要用函数 [!question] 有的同学会好奇,我们使用之前学习的内容,直接写我们要执行的代码不好吗?干嘛还要定义个函数,然后再调用它听起来这种听起来很麻烦的做法呢? 其实我们可以有这么一些个好处: (1)控制代码运行的开关。函数定义后,没有调用它的情况下是不会执行的,这样我们结合流程控制,可以智能地选择要运行的代码,当不想运行的时候,注释掉调用语句或者不写调用即可,用不着把大段的代码逻辑给注释掉或删除掉,非常方便。 (2)代码复用。函数为代码复用的重要手段,比如我们要计算一个我们想要的复杂的计算结果需要传入1个参数,然后跑200行的代码后才能获得正确的结果。如果没有函数,那么我们每次计算都写一遍这200行代码吗?这么做显然是低效而且浪费资源的。我们做程序员就是为了偷懒,别人辛辛苦苦干一天的活,我们整个自动化程序,自己跑个一小时就干完了,大大提高了生产力,所以重复的代码还是尽量交给计算机来完成比较好,这样我们有更多的时间来思考业务实现逻辑的优化。这也体现了封装的思想,将经常需要使用的相同或相似代码打个包,用到的时候拿出来玩玩,用不到的时候它就乖乖躺一边,多舒服啊。 当然使用函数还有其他一些好处,这里就不再赘述了。总之它很好,就对了。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:17:15 "},"chapter5/5-2 python3小白课:函数入门.html":{"url":"chapter5/5-2 python3小白课:函数入门.html","title":"5-2 python3小白课:函数入门","keywords":"","body":"python3小白课:函数入门 函数的定义和调用 定义一个函数很简单,用到def关键字来定义。我们来看一下语法: def 函数名([形参们]): [执行体] [return [返回值]] 上述语法中的[]表示里面的内容是可选的,可以填可以不填,不是列表的意思。 使用def来声明这是一个函数,接下来写函数的名字,跟变量的命名规则类似,这里就不赘述了,需要注意的是,函数名不要跟一些系统保留关键字、类型名等相同,否则会报错或者覆盖内置的函数,使内置函数在脚本中无法使用。所以函数名尽量有意义一些,根据你的业务场景来命名有意义的,你能理解的命名。 接下来是一个小括号,里面可以设定要传入的参数在执行体中的名字(这样在执行体中可以获取到传入的参数),也可以是一个不需要参数的函数。 函数的内里部分需要缩进(否则不算函数的一部分),这一点需要大家注意一下。 当需要这个函数在调用完成后对外返回内容的时候,可以使用return关键字来进行返回,但它不是必须的。如果没有返回值就不写,如果有返回值就写。可以是什么都不返回,也可以在一个空格之后填写返回值,返回值可以是各种我们之前学习的数据类型。 执行体和return语句不能同时不存在。如果你还没想好这个函数要做什么,可以使用学过的pass占位符占位。 [!danger] 在函数中,一旦碰到return语句函数就会立即结束调用并返回,即时在return语句的后面还有执行的语句也是不会执行的。所以它也可以用于结束循环结构的循环体。 我们来尝试定义一个十分简单的函数,并且调用它来理解: # coding:utf-8 def add_1(num): return num + 1 a = add_1(1) print(a) 这个例子是定义一个函数,这个函数可以让传入的值加上1之后返回。从这个简单的例子我们还能看到一些小知识点。 比如这是一个没有执行体部分的函数,但计算的逻辑代码写在了return语句的部分,所以return语句是支持表达式的。 形参传入了一个叫做num的变量,它是不允许为空的变量,必须传入值,否则调用函数时会报错。 函数返回之后,可以用变量接收结果进行进一步处理。函数的定义代码在调用之前,调用函数跟我们之前调用系统内置函数似乎区别不大。 同理,定义函数时不设定形参,就是一个不需要传入参数即可直接调用的函数,我们看个例子: # coding:utf-8 def print_3(): text = \"重要的事情说三遍!\" for i in range(3): print(text) print_3() 这个函数是重要的事情说三遍的函数实现,今后,你只需要带上这个函数,就可以一条命令调用这个功能了,十分方便。当然,如果你需要实现传入任意的话语都能自动说三遍,你也可以设定一个形参,传入你要说的话。 这个函数没有return语句,也是可以的。具体怎么写,你可以根据你的业务需要,灵活思考变动,举一反三。 函数多个返回值 刚才我们举的小例子都是返回一个返回值或者不返回的。 [!question] 那么同一个函数支持多个返回值吗? 在python中,是支持的。我们直接来看个例子: # coding:utf-8 def get_fruits(): return \"apple\", \"banana\", \"orange\" print(get_fruits()) 这个例子返回了三种水果的名字字符串,我们注意到在return语句中使用了,分隔,这样就可以返回多个返回值了,返回的返回值会自动组装成一个列表。 [!tip] 你可以使用一个变量接收后使用索引访问,也可以定义多个变量,用序列解包的方式赋值给每个变量。 为函数提供帮助文档 之前的课程中,我们学习过使用help命令来查看函数命令的帮助文档,这些文档是哪儿来的呢?其实这都是这些函数在创建之初,就定义好的供人查询用的。如果开发者懒一点没有定义,那么有可能你是看不到这个文档的。 [!question] 那么你自己编写的函数呢?可以自己定义文档吗? 答案是可以的,而且非常简单。 我们来看个例子。 # coding:utf-8 def get_fruits(): \"\"\" 我就是函数的文档,使用多行文本的写作方式就可以,写在函数执行体的前面 这个函数是支持中文的。 因为是多行文本,某一行你也可以选择不缩进,总之怎么方便怎么来。 你可以写任意的内容到文档里面 通常的写法是: 函数作用:获取几种水果的名字 参数:没有参数。如果有多个参数可以分多行写 返回值:没有返回值可以不写 你还可以写一些使用范例等等 写好之后,可以使用help命令来查看你写的效果,如果不喜欢,还可以修改 \"\"\" return \"apple\", \"banana\", \"orange\" print(get_fruits()) print(\"*\" * 40) print(help(get_fruits)) print(\"*\" * 40) # 你还可以使用函数的__doc__属性查看帮助文档,注意前后各有两个_ print(get_fruits.__doc__) 可见,有的时候定义一个函数的文档,内容甚至可能比代码的量还大,当然,如果你不想写那么多,也没有强制要求,你可以不写文档或者只写一两行,一切看你自己。 如果你写的函数文档是怕自己忘了或者给别人看的,还记得我们讲过的注释的好处吗?一个好的帮助文档是可以帮助团队省事的,要写多少,看你咯。 单词释义 单词 释义 def define定义这个单词的简写 return 返回 add 加,加法 num number数字的简写 text 文本 get 获取 fruits fruit是水果的意思,这里是复数形式 apple 苹果 banana 香蕉 orange 橙子,柑橘 help 帮助 doc document文档这个单词的简写 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:20:13 "},"chapter5/5-3 python3小白课:递归函数.html":{"url":"chapter5/5-3 python3小白课:递归函数.html","title":"5-3 python3小白课:递归函数","keywords":"","body":"python3小白课:递归函数 递归函数的定义 在一个函数的定义中,可以调用其他函数来完成一些操作。但如果在函数的定义内部调用函数自身(即自己调用自己),那么这个函数就称之为递归函数,递归函数是一种有趣的函数定义形式,在某些业务场景之下十分便利。比如文件层级遍历、目录树、一些数学算法等。 本节课我们就拿一个简单的数学算法来讲讲递归函数是如何定义的以及注意点。 引用百科的内容: 斐波那契数列(Fibonacci sequence),又称黄金分割数列、兔子数列,是数学家列昂纳多·斐波那契于1202年提出的数列。 斐波那契数列为1、1、2、3、5、8、13、21、34……此数列从第3项开始,每一项都等于前两项之和,递推公式为F(n)=F(n-1)+F(n-2),n≥3,F(1)=1,F(2)=1。 在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1963年起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。 要完成斐波那契数列的递推生成,使用递归函数就是一个不错的选择。我们先来看一下代码: # coding:utf-8 def fib(n): if n in [1, 2]: return 1 else: return fib(n - 1) + fib(n - 2) fib_seq = [fib(i) for i in range(1, 31)] print(fib_seq) 如代码所示,我们通过for表达式循环获取了一个斐波那契数列列表,共30个元素,传入是要求这个n要大于等于1,这里就不写其他的判断语句了,为了说明的简洁。 可以看到进入函数之后,首先判断n是否为1或者2,如果是的话,则是固定的数1,如果大于等于3的话,就会返回调用自身函数的表达式,只不过传入的参数变成了n -1或者n - 2。这样传入之后,就会各自调用自身来进行计算,当减少到一定程度之后,一定会到获取fib(1)、fib(2)的值,而这两个值是固定的,为1。所以整个函数调用得以结束。 [!danger] 编写递归函数时,当自身自调用到一定程度的时候,它能够获取确定的值,不再调用自身,如果不能,就会形成一种死循环,这是无意义的。 因此在写递归函数的时候,需要注意,递归一定要朝着已知的方向进行。 防止堆栈溢出 [!note] 这部分是比较偏底层原理的内容,如果不好理解,可以跳过。 使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。 [!danger] 因此我们在使用递归函数的时候,需要注意调用递归的层级不要太深,太深容易导致栈溢出,会报错,在python中目前没有良好的机制来处理,所以是存在这个问题的。 多深呢?比如上千层的递归调用。 还有一种情况是递归程度深,系统运算困难,速度慢。就拿刚才讲到的斐波那契数列来说,我们把代码改成这样: 这次我们一次次获取数列中的每个值,打算跑1000次。 # coding:utf-8 def fib(n): if n in [1, 2]: return 1 else: return fib(n - 1) + fib(n - 2) for i in range(1, 1001): print(\"i: %s, fib(i): %s\" % (i, fib(i))) 我们来运行看一下效果。 可以看到随着递归层级的加深,运算速度也在逐步减慢,有的时候甚至半天出不来一个结果了。 [!danger] 因此我们在实际运用中,注意递归层级不要过深。 单词释义 单词 释义 Fibonacci sequence 斐波那契数列,fib,seq为长单词短写,本身不是单词 stack 栈,你可以理解为在一个容器中一块块放入木板,为加一层栈 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:23:34 "},"chapter5/5-4 python3小白课:关键字参数.html":{"url":"chapter5/5-4 python3小白课:关键字参数.html","title":"5-4 python3小白课:关键字参数","keywords":"","body":"python3小白课:关键字参数 定义函数的时候我们可以设定形参,而在调用函数的时候需要传入对应的参数,我们最简单的方式是直接按定义时的顺序传入,这时候传入的参数就叫做位置参数。它会按照传入的位置赋值给对应的形参。 # coding:utf-8 def info(name, age): print(\"姓名:%s,年龄:%d\" % (name, age)) info(\"小白\", 18) 但我们有的时候记不住这个顺序,或者想只赋值其中的几个参数的时候,就不一定要按照定义的顺序来了,我们可以使用关键字参数来定义。关键字参数就是在调用的时候使用关键字=值的定义形式,这样解释器就能够自动的关联到对应的形参了。 看个例子: # coding:utf-8 def info(name, age): print(\"姓名:%s,年龄:%d\" % (name, age)) info(age=18, name=\"小白\") 运行后可以看到,也是能够正确的匹配的。 如果我们在调用时,有时候用位置参数,有时候用关键字参数调用,可以吗?答案是可以的。但我们需要注意一个原则,就是位置参数必须写在关键字参数之前,否则解释器会搞不清你要将传入的参数赋值给哪个形参,导致报错。 # coding:utf-8 def info(name, age, sex): print(\"姓名:%s,年龄:%d,性别:%s\" % (name, age, sex)) # 这样写会报错: # info(age=18, sex=\"男\", \"小白\") # 正确的写法 info(\"小白\", sex=\"男\", age=18) 单词释义 单词 释义 info information信息的简写形式 name 姓名 age 年龄 sex 性别 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-10 16:03:54 "},"chapter5/5-5 python3小白课:参数默认值.html":{"url":"chapter5/5-5 python3小白课:参数默认值.html","title":"5-5 python3小白课:参数默认值","keywords":"","body":"python3小白课:参数默认值 在某些情况下,我们还能给函数在定义时设定参数的默认值,这样在调用的时候,我们可以做到当不传入参数时,则自动使用默认值,如果传入参数,则使用传入的参数,大大丰富了我们的业务场景。 # coding:utf-8 def info(name, age=18, sex=\"男\"): print(\"姓名:%s,年龄:%d,性别:%s\" % (name, age, sex)) info(\"小白\") info(\"小黑\", 20, \"女\") info(\"小红\", sex=\"女\") 定义默认值的方式很简单,在定义形参的时候使用形参名=默认值的方式定义即可。需要注意的是,定义了默认值的参数必须放在没有定义默认值的参数的后面,还是那个解释器不好找不好对应参数的问题。 这里我们给两个参数定义了默认值,它们就变成了选填参数,在实际调用的时候,就只需要传递第一个参数即可,第一个参数没有定义默认值,所以我们也称之为必填参数。 当然我们也可以几个参数都赋值,这样就会应用我们赋值进去的值。 结合我们学习过的关键字参数,我们还可以跳着赋值,比如只赋值第一、第三个值,这就是关键字参数赋值的另一种运用场景。 [!tip] 在一些别人定义好的函数当中,可能也会大量的定义包含默认值的参数,使用位置参数+关键字参数结合的调用方法,就可以很方便的调用函数了。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:24:13 "},"chapter5/5-6 python3小白课:参数收集.html":{"url":"chapter5/5-6 python3小白课:参数收集.html","title":"5-6 python3小白课:参数收集","keywords":"","body":"python3小白课:参数收集 普通参数收集 python跟很多编程语言一样,支持定义个数可变的参数,这样定义起来很方便,也能支持处理多个传入的参数。 在定义形参的时候,我们可以在形参前面添加一个*星号用来表示这个形参支持接收多个参数值,多个参数值会自动组装成元组并传入,在函数内部我们就可以使用处理元组的方式来处理传入参数了。 # coding:utf-8 def info(name, *nickname): print(f\"您的名字为:{name}\") print(f\"您的昵称有这些:{nickname}\") info(\"小白\", \"little bai\", \"白白\", \"小白白\", \"超级白\") 这里我们使用了f-string来格式化文本,这里的第一个参数被赋值给name这个形参,而后面不论增加赋值多少个参数,都会组合成元组,赋值给nickname,需要注意的是,在函数内部调用nickname的时候,不需要带*号。 [!danger] 这种带一个*号的能收集参数的形参在同一个函数中仅能定义一个,因为多了解释器就不好识别并自动分配了。 这样的形参还能放在前面,我们看个例子: # coding:utf-8 def info(*nickname, name): print(f\"您的名字为:{name}\") print(f\"您的昵称有这些:{nickname}\") info(\"little bai\", \"白白\", \"小白白\", \"超级白\", name=\"小白\") 由于加*的形参支持读取可变个数的参数,因此其他的参数,解释器默认不能正常找到,如果我们要赋值给name参数,就必须使用关键字参数,而关键字参数需要在调用参数的最后来写,所以就写成了我们上述代码的样子。 关键字参数收集 除了之前一个*的普通关键字收集,python函数在定义时,还支持在形参前加两个*号,即**形参名,这样写后,会将传入的关键字参数收集成字典,在函数内部可以调用。 [!danger] 同样的,在同一个函数定义中,也只允许有一个关键字参数收集的参数定义。 不过,关键字参数的收集可以跟普通参数收集同时存在。 具体的使用大家可以根据自己的业务场景来设计,我们来看个简单的使用。 # coding:utf-8 def info(name, *nickname, **score): print(f\"您的名字为:{name}\") print(f\"您的昵称有这些:{nickname}\") print(f\"您的成绩为:{score}\") info(\"小白\", \"little bai\", \"白白\", \"小白白\", \"超级白\", 语文=89, 数学=99) 你也可以在函数内部使用字典的方法来获取内容。 逆向参数收集 除了前面讲的正向的参数收集,python函数定义还支持逆向参数收集。 # coding:utf-8 def info(name, nickname): print(f\"您的名字为:{name}\") print(f\"您的昵称为:{nickname}\") a = [\"小白\", \"白白\"] info(*a) 我们再来看一个传入字典的逆向收集。 # coding:utf-8 def info(name, nickname, score): print(f\"您的名字为:{name}\") print(f\"您的昵称为:{nickname}\") print(f\"您的成绩为:{score}\") a = { \"name\": \"小白\", \"nickname\": \"白白\", \"score\": 94 } info(**a) 这样函数就会自动寻找字典中的键来匹配了。我尝试了一下,如果字典中多定义一个键,发现会报错的。所以函数需要哪几个,就传入哪几个键的字典就好了。 单词释义 单词 释义 nickname 昵称,外号 name 姓名 score 成绩 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 17:24:53 "},"chapter5/5-7 python3小白课:变量作用域.html":{"url":"chapter5/5-7 python3小白课:变量作用域.html","title":"5-7 python3小白课:变量作用域","keywords":"","body":"python3小白课:变量作用域 我们定义的变量,是有作用域范围的。作用域是什么呢?就是这个变量在哪里能被调用,在哪里不能。 就拿我们学过的没在函数里面直接定义的变量和在函数内部定义的变量来说,它们的作用域就不同。 我们分成如下两种: 全局变量。在函数外部定义的全局可用的变量。 局部变量。在函数内部定义的,也包括参数,仅在函数内部可调用的变量。 每次函数在执行时,系统会自动给这个函数的调用分配一块临时内存空间用来存储局部变量,当函数调用结束,这块内存空间就会被释放,局部变量也就失效了。 但全局变量是在python脚本运行时分配的内存空间,在函数外可以调用,在函数内也可以调用的。 我们来看点例子: # coding:utf-8 name = \"小白\" def test(): print(name) test() 运行后可以发现,我们能在函数中访问到全局变量。 我们再来看下如下代码: # coding:utf-8 name = \"小白\" def test(): name = \"小黑\" print(name) test() 我们来运行一下,发现输出的结果为小黑。 这是因为在函数内部,重新定义了name变量,这样前面定义的全局变量就被遮蔽了。那么我们要不试试先输出全局变量看下? # coding:utf-8 name = \"小白\" def test(): print(name) name = \"小黑\" print(name) test() 运行发现,程序报错了,提示UnboundLocalError: local variable 'name' referenced before assignment。即告诉你局部变量name还没有定义。还是那个原因,因为在函数内部有定义name局部变量的语句,全局变量就被遮蔽了,所以按python的规定,在运行第4行的时候就找不到局部变量name了。 为了避免在函数中对全局变量赋值,我们可以使用global语句来声明全局变量,上述错误代码可以改成这样: # coding:utf-8 name = \"小白\" def test(): global name print(name) name = \"小黑\" print(name) test() print(name) 我们可以看到,这次不再报错了,并且首先打印出了小白,然后打印出了小黑,最后打印出了小黑。 这是因为我们把name声明为了全局变量,后续一切更改和打印都是基于全局变量的操作,就没有局部变量存在了。 关于全局变量、局部变量大家可以根据自己的业务需要来再仔细研究一下,但为了大家写代码和理解方便,通常来讲,如果在函数中调用了全局变量的,不要修改它的值,以免造成其他问题。如果确实需要修改全局变量的,可以使用global语句将变量定义为全局变量,后续的修改就是基于全局变量的了。 单词释义 单词 释义 test 测试 UnboundLocalError unbound,unbind的过去式,未绑定的,local,局部,本地,error,错误 local 局部,本地 variable 变量 referenced reference的过去式或被动式,理解为被引用 before 在...之前 assignment 分派,布置,理解为赋值吧这里 global 全球的,全世界的,这里理解为全局 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 10:07:00 "},"chapter5/5-8 python3小白课:局部函数.html":{"url":"chapter5/5-8 python3小白课:局部函数.html","title":"5-8 python3小白课:局部函数","keywords":"","body":"python3小白课:局部函数 局部函数定义 前面我们学习的函数都是在全局范围内定义的,在整个py脚本中都可以调用到它。如果在函数定义的内部再定义函数呢?python也是支持的,这时候的函数就称之为局部函数。 接下来我们把在全局范围定义的函数称为封闭函数,封闭函数内定义的函数称之为局部函数。默认情况下,局部函数对外是隐藏的,仅能在封闭函数内进行调用。但你也可以做出一些变动,让外部也能调用到局部函数来进行计算。 我们来看个小例子: # coding:utf-8 def fengbi(method, num): def add_1(num): return num + 1 def add_2(num): return num + 2 def add_3(num): return num + 3 if method == \"add_1\": return add_1(num) elif method == \"add_2\": return add_2(num) elif method == \"add_3\": return add_3(num) else: return \"不支持的方法名\" print(fengbi(\"add_1\", 1)) print(fengbi(\"add_2\", 1)) print(fengbi(\"add_4\", 1)) 由于直接在内部定义并调用比较简单我们就不举例子了。我们来举一个从外部调用到内部局部函数的方法例子,这里我们定义了一个封闭函数,支持传入方法名,在函数内部首先定义好那几个局部函数方法,后续可以通过if结构判断给的是什么方法,来调用具体的局部函数返回。 局部函数访问封闭函数中的局部变量 [!note] 本部分知识比较不常用,可以学习也可以跳过。 由于我们这里在函数内部又有函数定义,势必有可能会遇到在局部函数中调用到封闭函数中定义的局部变量的情形。此时还是跟之前学习作用域时讲的一样,可以在局部函数中直接调用在封闭函数中定义的局部函数。(这么听起来比较拗口,我们看个例子吧) # coding:utf-8 def fengbi(): num = 1 def add_1(): return num + 1 print(add_1()) fengbi() 可见,是可以直接访问的。如果我们在局部函数中修改封闭函数中的局部变量呢? # coding:utf-8 def fengbi(): num = 1 def add_1(): print(num) num = 2 return num + 1 print(add_1()) fengbi() 这次运行又报错了,报错信息为:UnboundLocalError: local variable 'num' referenced before assignment,看起来还是我们讲变量作用域时说过的问题。怎么解决呢?此时我们就不用global语句了,因为那是对付全局变量的。我们可以使用nonlocal语句来解决,用法跟global语句是一致的。 # coding:utf-8 def fengbi(): num = 1 def add_1(): nonlocal num print(num) num = 2 return num + 1 print(add_1()) print(num) fengbi() 此时我们会发现,num在上述代码中就一直指代封闭函数中的num局部变量了,不会有报错的情况发生,对于num的修改也会造成num局部变量的值改变。 如果你对这部分知识感兴趣,可以往下学习我们下面的函数:前沿部分。 函数:前沿 关于函数的知识,我们还有一些高级内容,但作为入门小白,经过审慎考虑,我认为像市面上一本百科全书一样把一个东西讲得太多太难太细对大家是没有太大帮助的,大家只会学着学着感叹,哇呀,怎么函数这么难?这么多知识这么难记?哇呀,python太难学了我不学了。 为了避免大家出现这种难过的情绪,我希望大家始终保持必要的学习激情,我们前面讲过的知识,基础运用是非常简单的,如果你对于某一块有兴趣,可以找找网上的资料,进一步自学即可,在入门时不必太过于执着和纠结你听不懂记不住的知识,够用就好。 [!note] 关于函数的一些更难的知识,我们将会安排在进阶或高级课程中跟大家一起去啃这些硬骨头,它们适合python编程已经有一定基础,想要进一步突破瓶颈的同学。 这里我们就着前面讲过的内容,再扩展一点点前沿知识,如果你学不会看不懂,请跳过,没有关系的,当你做好了进一步突破瓶颈的准备,比如在一个美好的清晨,你休息得很好,脑袋适合研究点什么,再回过头来听一听你感兴趣的内容。 ***华丽的分割线*** 好,给大家随便灌了点鸡汤,我们继续讲课。 函数还有比较高级的定义方法,因为函数本身是一个对象,所以函数本身既可以用于赋值,也可以用于作为调用的参数传进别的函数中,还可以作为其他函数的返回值。 这里我们来讲个小例子,看下函数作为返回值是怎样的。 # coding:utf-8 def createCounter(): n = 0 def counter(): nonlocal n n += 1 return n return counter # 验证计数器 mycounter = createCounter() for i in range(5): print(mycounter()) 这是从网上找到的一个小题目,代码也是参考了下网上的朋友的,做了一些优化修改。 我们的题目是定义一个函数计数器,这个计数器内部可以存档一个计数,每次调用函数的时候,可以实现计数次数的增长。 首先我们可以先跑一下运行结果,可以看到每次输出的结果都会自增1,分别输出1, 2, 3, 4, 5这几个值来。 然后我们来分析一下代码。 首先我们定义了一个createCounter创建计数器的函数,这个函数内部呢,定义了一个n变量,这个变量就是计数器的值了。接着我们定义了一个counter的局部函数,这个函数就使用了我们前面讲到的nonlocal语句,申明局部函数用到的n变量是用的封闭函数中的那个,这样后续赋值就不会重新定义一个n变量了,实现了访问变量的目的。接下来在局部函数内将变量的值自增1,并返回最新的结果。 需要注意的是,这个createCounter函数的return语句返回的是一个函数,如果返回函数counter,直接写函数名即可,没有括号什么的。 这样返回如何调用呢?首先运行这个createCounter函数,将它的返回值赋值给一个变量mycounter,此时mycounter就有了counter函数的功能了。接下来在调用时,只需要调用mycounter这个函数即可。 [!note] 这是一种闭包的概念,如果我们的n是一个全局变量,那么这个计数器在每次使用时,你还需要在自己的代码中定义它,或者需要查看这个函数内部的代码实现。 当使用闭包后,变量n的作用域仅限于封闭函数中,这在某些时候就给了使用者一些便利。 在python脚本运行期间,每次调用,我们会发现n的值,是在不断自增的,你可以理解为,我们只访问了counter函数,并没有再次访问createCounter函数,所以这个n不会重新赋值,而counter函数又能访问到n并自增,这样就实现了一个计数器的效果。 是不是很有意思呢? [!note] 关于函数还有其他知识点,我们在入门课就不跟大家讲那么深那么难了,感兴趣的同学可以关注我们的进阶或高级课程学习或者自行网上查阅资料学习。 单词释义 单词 释义 method 方法 nonlocal non为否定前缀,local为局部的,在这里理解为非局部的 createCounter create创建,Counter计数器,count计数,合起来理解为创建计数器 counter 计数器 mycounter my我的,理解为我的计数器 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 19:17:28 "},"chapter6/":{"url":"chapter6/","title":"六、模块和包","keywords":"","body":"六、模块和包 之前的章节,我们学习了许多python自带的命令,它们在安装好python后就自带的,可以直接使用。但python的功能就仅限于那些吗?剩下的都需要自己定义吗? 当然不可能! python之所以能被各行各业广泛应用,我们之前已经说过,是它有着十分强大的生态系统,这个系统这里我们可以说到很大一部分是它的模块化系统。除了内置函数,python还有内置的模块,这些模块里面又有许许多多已经定义好的函数命令可以供我们使用。 如果你觉得这些还不够,全世界有许许多多的开发者都可以参与模块的贡献,它们可以可以把自己开发的模块(我们称之为三方包)上传到python官方提供的站点中,供全世界开发者免费下载。 我们称这些模块为轮子,可能你听过一句话是不要重复造轮子,说的就是如果别人开发有,且好用的话,你就拿来用就可以了。有了很多趁手的工具,我们的编程就可以事半功倍。这些扩展库也形成了python的生态圈。 如果这些还不够你用怎么办?你还可以自己定义模块,我们会在课程中学习到它。 当模块中的内容比较庞杂,变量、函数、类(类的知识,我们将在后面的章节讲解)等较多的时候,我们使用单文件来编写模块会使得这个文件非常庞大,不利于维护,不利于模块化开发。 所以我们还引入了包的概念,通过包,我们可以把这些东西都管理起来,方便后续的调用,本章节我们也会进行学习。 请大家进入我们的学习吧! Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 19:21:13 "},"chapter6/6-1 python3小白课:模块的导入.html":{"url":"chapter6/6-1 python3小白课:模块的导入.html","title":"6-1 python3小白课:模块的导入","keywords":"","body":"python3小白课:模块的导入 python安装后,就自带有许多内置的模块,我们可以导入它们来增强我们的代码功能。 [!tip] python安装非自带的需要你联网下载安装或离线安装的后续我们称之为三方库,导入三方库的方法和导入内置模块的方法一致,区别在于本机使用这些三方库前需要先安装而已。 模块的导入通常有以下两种语法: import 模块名1[ as 别名1], 模块名2[ as 别名2], ... from 模块名 import 成员名1[ as 别名1], 成员名2[ as 别名2], ... 上述语法中的方括号表示里面的内容可选填。 关于单词的含义大家可以看一下本节课结尾的单词释义。 第一种导入方式为导入整个模块,如果你导入多个模块,中间使用,隔开。有时候模块名你不喜欢或太长不好打不好记,你也可以用as给导入的模块指定别名,在后续的代码中可以通过别名来调用模块命令。后续代码中调用时,需要使用模块名或别名.成员名的方式调用。 第二种导入方式是从某个模块里导入成员,成员可以是函数,也可以是变量、类(关于类的知识,我们将在后面的课程中讲解)等其他东西。成员也可以一样的设置别名,支持导入多个成员。后续代码中调用时,可以直接使用成员名来进行调用。如果你需要导入模块中的所有成员,也可以写成from 模块名 import *,*代表所有,但我们一般不推荐这么做。 [!warning] 使用from 模块名 import *语句进行模块导入,会让代码降低可读性,别人在读你的代码时,会不知道你一股脑的导入了什么。另外,当模块中比如有函数的名字跟你的代码中定义的函数名字相同时,也会受到影响。 [!question] 为什么有两种导入方式呢? 我想是因为重名的原因,有些模块定义的函数等可能跟你自己在代码中定义的重名,使用第一种方式就不会起冲突。但也有时候模块命令使用第一种方式调用太长太繁琐,自己的代码中也没有什么冲突的,那么第二种方式是一种省事的选择。具体使用哪一种,可以根据自己的业务需要来决定。 我们来看点例子: # coding:utf-8 import sys import os print(sys.argv[0]) print(os.listdir(\".\")) 这里我们导入了自带的sys和os两个模块(有的时候习惯叫法可能也会叫做包,如果后续我称之为包,也不要奇怪)。它们的作用,你可以自行使用help命令查看。 [!danger] 记得模块需要先导入,才能看帮助文档。 导入后,可以使用模块名.成员名的形式调用,如果是函数,还能传入参数,如果是可迭代对象(比如是个列表、元组等),可以传入索引等等。我们这里尝试了这俩模块里的俩命令。第一个是获取python程序运行时的命令行参数,第一个元素为python脚本的名字。第二个是获取指定路径的文件和文件夹列表,传入的参数表示脚本所在的当前文件夹。 可以看到,引用模块非常之简单。我们再来看下其他写法: # coding:utf-8 import sys as s import os as o print(s.argv[0]) print(o.listdir(\".\")) 指定别名之后,可以使用别名。 我们来看一下另一种导入方式的例子: # coding:utf-8 from sys import argv as aaa print(aaa[0]) 可以看到,使用第二种导入方式可以直接导入成员,也能指定成员的别名,后续调用时,只需要使用成员名或者指定的别名即可调用,无需添加模块名。 [!danger] 如果没有指定别名,需要注意成员名跟你自己写的代码中定义的成员不能重名。 如果指定了别名,需要注意指定的别名跟你自己写的代码中定义的成员不能重名,此时模块的原成员名可以重名没关系。 我们再来看个例子: # coding:utf-8 from sys import * print(argv[0]) 这里我们使用了from 模块名 import *的写法,导入了sys模块的所有成员,也可以直接调用里面的成员。但你需要很了解里面有什么命令,降低了可读性,而且也只能使用内部成员原本的名字,也可能导入了一些不必要的成员造成程序有重名的风险。所以一般情况下,我们不太推荐这么写。 单词释义 单词 释义 import 导入 as 作为... from 从...哪里 sys system系统的简写 os operating system操作系统的简写 argv 查一下,为argument vector,参数向量,指的应该是传入的参数列表 listdir list列举,列表,dir,directory目录,命令可以枚举给定路径的文件和文件夹 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-11 20:16:55 "},"chapter6/6-2 python3小白课:自己写模块.html":{"url":"chapter6/6-2 python3小白课:自己写模块.html","title":"6-2 python3小白课:自己写模块","keywords":"","body":"python3小白课:自己写模块 模块定义 要自己写一个模块,语法也非常非常简单,其实模块就是一个自己写的python脚本文件!你可以在一个py文件中定义变量、函数、类等等内容,保存起来,就是一个模块了。模块的名字就是这个py文件的文件名! 因此这节课我们来学习定义一个简单的自己的模块吧! 定义模块练习我们就定义一个简单的函数吧,将下面的代码保存成mymodule.py文件吧: # coding:utf-8 def add_1(num): return num + 1 这样我们就定义好了一个最简单的模块,里面的函数就是其中一个成员,我们可以在别的py文件中导入并使用,将你的模块文件跟你的测试py文件放在同一个目录下即可。 模块的说明文档 除了可以给函数添加说明文档,你还可以给模块添加说明文档。在所有可执行的代码前面使用长文本字符串定义说明文档即可,我们在刚才的文件前面补充一下: # coding:utf-8 \"\"\" 模块名:mymodule 小白同学的第一个模块 这是说明文档 命令:add_1(num) 将传入的数字加上1后返回 \"\"\" def add_1(num): \"\"\"将传入的数字加上1后返回,这是函数的文档\"\"\" return num + 1 编写完成后,我们可以在其他地方导入该模块,使用help命令即可查看模块帮助文档,也可以访问模块的__doc__属性。 比如我们再在同一个目录下定义一个test.py文件: # coding:utf-8 import mymodule help(mymodule) print(\"*\" * 40) print(mymodule.__doc__) print(mymodule.add_1(1)) 我们还顺便测试了一下里面定义的函数。 [!tip] 成功运行后,我们可以发现在模块所在目录下看到一个名为__pycache__的文件夹,里面会为模块生成一个.pyc文件,这是python为模块编译生成的字节码文件,是用来提升模块运行效率的,你知道并忽略它即可,将模块复制走的时候无需带上它。 模块的测试代码 [!question] 模块写好之后,只能通过外部导入模块来进行测试吗? 非也,别忘了模块本身也是一个python脚本文件,它自己也能跑起来。我们可以自行在模块的文件中定义一些函数或者执行语句来测试我们编写的模块,但如果写的是执行语句的话,这些语句会在导入模块时运行一遍。但我们在使用时,是不希望执行测试代码的。 别急,python中有一种不错的机制可以满足你的需求。 [!tip] python模块有一个内置的变量__name__,如果直接执行模块的代码,这个变量的值就为__main__,但如果是通过外部导入模块的方式,这个变量的值为模块的名字。 利用这个机制,我们可以在模块的结尾编写流程控制来区分是导入模块还是直接执行,看下如下模块代码: # coding:utf-8 \"\"\" 模块名:mymodule 小白同学的第一个模块 这是说明文档 命令:add_1(num) 将传入的数字加上1后返回 \"\"\" def add_1(num): \"\"\"将传入的数字加上1后返回,这是函数的文档\"\"\" return num + 1 if __name__ == '__main__': print(\"这是在测试模块\") help(__name__) print(\"*\" * 40) print(__doc__) print(add_1(100)) 这样,如果是直接运行这段代码,就会运行17~21行的部分代码了,但如果是导入模块的话,这部分代码就不会被执行。 [!tip] if __name__ == '__main__':这种写法,在你的一个普通的py脚本文件中也可以这么用的,不一定是在模块中才能用。 单词释义 单词 释义 mymodule my我的,module模块,我的模块的意思 name 名字 main 主要的 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-13 23:33:26 "},"chapter6/6-3 python3小白课:导入模块详解.html":{"url":"chapter6/6-3 python3小白课:导入模块详解.html","title":"6-3 python3小白课:导入模块详解","keywords":"","body":"python3小白课:导入模块详解 哪儿导入我们的模块? [!question] 编写好模块之后,我们可以把模块放在哪里供我们的其他py程序导入和使用? 我们通常有两种方式: 使用环境变量 从默认模块加载路径导入 使用环境变量 这种方式我不太用,说的是可以在系统环境变量中,添加一个名为PYTHONPATH的环境变量,这个变量的值支持多个路径值,可以支持在多个路径寻找。比如我们可以设置d:\\test进去试一试。如果加入用户变量则只对当前用于生效,如果加入系统变量则可以对所有用户生效。系统变量的查找优先顺序大于用户变量。 从默认模块加载路径导入 我们可以通过sys.path查看模块的默认导入路径有哪些。 # coding:utf-8 import sys, pprint # pprint可以替代print函数,在需要输出的内容较多时,可以更友好的显示打印结果 pprint.pprint(sys.path) [!tip] 可以看到,默认都会从我们的脚本所在的同一个目录导入,多数时候,我们放在同一个目录下是最方便的。 同时也会有些python的安装目录等。 在这里,我们需要注意到一个目录,今后我们安装一些三方库的时候,通常都是会安装到python安装目录下的lib\\site-packages目录下的,因此如果你需要将自己写的模块放到一个python目录下,通常可以放到这个目录下。 你还可以临时性扩展这个列表: # coding:utf-8 import sys, pprint sys.path.append(\"d:\\\\test\") pprint.pprint(sys.path) import mymodule help(mymodule) print(\"*\" * 40) print(mymodule.__doc__) print(mymodule.add_1(1)) 这里可以承接我们之前课时中讲过的已写好的模块来测试。 [!tip] 这样的添加是临时的,运行另外的python脚本程序这个路径就不会再找了,也不会影响系统环境变量等,也是一个比较推荐的编写方式。 模块的__all__变量 之前我们讲过,使用from 模块名 import *这样的语句会导入模块的所有成员。但有的时候我们不希望我们的每个成员都供外界使用,这时我们可以在模块中定义一个__all__变量,它是一个列表,我们想像外界暴露什么就写进去,没写的就不会暴露。 我们尝试定义一个mymodule.py文件如下: # coding:utf-8 def add_1(num): return num + 1 def add_2(num): return num + 2 def add_3(num): return num + 3 __all__ = [\"add_1\", \"add_2\"] 我们再在同一个目录下定义一个test.py文件用来测试: # coding:utf-8 from mymodule import * print(add_1(1)) print(add_2(1)) print(add_3(1)) 此时运行它,就会发现报错,会发现add_3这个命令找不到。这个变量就实现了它的意义。 [!question] 如果定义了这个变量,还是需要使用没在列表里面的成员怎么办呢? 可以使用import 模块名导入模块,这样是可以访问到的。 使用from 模块名 import 成员名导入成员,这样也是可以导入的。 具体大家可以试一下哦~ 参考例子: # coding:utf-8 from mymodule import add_1, add_2, add_3 print(add_1(1)) print(add_2(1)) print(add_3(1)) 单词释义 单词 释义 PYTHONPATH path,路径,pythonpath在这里是python脚本查找模块的路径 path 路径 lib 通常指程序的一些库文件 site-packages site网站,站点,packages,package包的复数形式,合起来理解为一些三方包吧 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-13 23:53:18 "},"chapter6/6-4 python3小白课:包是什么.html":{"url":"chapter6/6-4 python3小白课:包是什么.html","title":"6-4 python3小白课:包是什么","keywords":"","body":"python3小白课:包是什么 [!question] python中除了模块,还有一中叫做包的叫法,那么它究竟是什么呢? 事实上,我们可以在一个模块中包含可供外界调用的各种成员,但当里面的成员非常多的时候,模块的维护会变得困难。这时候包(package)就出现了,它可以把一个冗长模块中的成员拆成多个py文件模块,然后统一放到一个文件夹里,文件夹的名字就是包名。后续在使用时,可以像模块几乎一致的语法来使用包,如导入模块时,导入文件夹名作为模块名即可。 从这个角度看,包其实也是一种模块,只不过它比单文件更加好维护和扩展。包是一个文件夹,而且python不是会轻易认任何一个文件夹为包的,我们在定义这个文件夹为包的时候,需要在这个文件夹的根目录创建一个文件__init__.py。这是一个初始化包的文件,它可以不写任何内容,python遇到这种文件夹的时候就知道它是一个包了。 导入包跟导入模块是一样的写法,python寻找包的方式也跟我们讲过的导入模块详解中的内容一致,这里就不赘述了。 在编写包代码的时候,可以仅将模块所有代码写在__init__.py这个文件下。此时导入包时,会自动执行该文件中的所有代码。 另一种方式是在文件夹中将你的模块代码拆分成多个py文件,每个文件有自己的名字,它们就是包中的子模块,__init__.py这个文件完全可以留空。 给包编写帮助文档也很简单,使用多行字符串的方式在包中的__init__.py文件或其他py文件最前面写帮助文档即可。 关于定义包、导入包的知识,我们将在后面的课程中详细讲解。 单词释义 单词 释义 package 包 init 初始化 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-14 21:41:15 "},"chapter6/6-5 python3小白课:定义包.html":{"url":"chapter6/6-5 python3小白课:定义包.html","title":"6-5 python3小白课:定义包","keywords":"","body":"python3小白课:定义包 在__init__.py文件中定义包 我们可以单独在单文件中定义包,接下来我们来尝试一下。 首先创建一个文件夹名叫xiaobai,它就是未来的包名和导入名了。在文件夹中创建__init__.py文件,并编写如下内容: # coding:utf-8 \"\"\" 小白同学的包 这是说明文档 命令:add_1(num) 将传入的数字加上1后返回 \"\"\" def add_1(num): \"\"\"将传入的数字加上1后返回,这是函数的文档\"\"\" return num + 1 if __name__ == '__main__': print(\"这是在测试模块\") help(__name__) print(\"*\" * 40) print(__doc__) print(add_1(100)) 该文件可以自执行来测试。 接下来我们在跟xiaobai这个文件夹同级的目录下创建一个test.py文件,编写代码如下: # coding:utf-8 import xiaobai help(xiaobai) print(\"*\" * 40) print(xiaobai.__doc__) print(xiaobai.add_1(1)) 执行该文件,发现确实导入包就会导入__init__.py这个文件。 包内定义多个py文件 接下来我们尝试在包中的多个py文件中定义几个子模块吧。 此时__init__.py这个文件创建后留空,什么也不写。 我们在xiaobai这个包文件夹下创建一个名为module1.py的py文件,编写内容如下: # coding:utf-8 \"\"\" 我是module1 \"\"\" NAME = \"小白\" AGE = 18 创建一个名为module2.py的文件,编写内容如下: # coding:utf-8 \"\"\" 我是module2 \"\"\" def add_1(num): return num + 1 [!tip] 你还可以多定义几个文件,把你原本的模块拆成子模块,这样每个文件内容可能都会变少,或者更加明确分类,这对于后续的维护帮助很大。 接下来我们在跟xiaobai这个文件夹同级的目录下创建一个test.py文件,编写代码如下: # coding:utf-8 from xiaobai.module1 import NAME, AGE import xiaobai.module2 as mod2 print(NAME, AGE) print(mod2.add_1(100)) 这里仅做了简单的调用示例,可以正常获取到模块的成员内容并调用。 后续我们将再详细讲解调用包中的成员的更多知识。 包中定义子包 当包的大小达到一定程度之后,感觉又不好维护了,或者这个包本身就是由好几个团队分别维护的,这时候这个包就很大功能很全。 由于我们讲过包其实本质也是模块,那么在包中再嵌套多个文件夹,每个文件夹像包一样的定义好,形成包中的子包,也是支持的。 关于这个,你知道了解即可,我们就不进行深入探讨了。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-16 14:39:20 "},"chapter6/6-6 python3小白课:包成员导入.html":{"url":"chapter6/6-6 python3小白课:包成员导入.html","title":"6-6 python3小白课:包成员导入","keywords":"","body":"python3小白课:包成员导入 包成员导入的一般方法 这部分讲的方法比较适用于在__init__.py文件中未做其他操作或者该文件为空的场景。 我们就拿上节课讲到的定义的xiaobai这个包来说起。 我们再回顾一下这几个文件的内容: module1.py文件: # coding:utf-8 \"\"\" 我是module1 \"\"\" NAME = \"小白\" AGE = 18 module2.py文件: # coding:utf-8 \"\"\" 我是module2 \"\"\" def add_1(num): return num + 1 基于上述内容我们有如下一些说明的导入用例,用于写在test.py文件中(它不是一个可用用例,只是为了解释说明一些导入的方法): # coding:utf-8 # 直接导入xiaobai包,实际上就是导入__init__.py文件 import xiaobai # 可以导入包中的子模块,如果未指定别名,使用时需要用导入的这么一长串来作为调用前缀 import xiaobai.module1 # 这种方式导入子模块,调用时前缀能稍微短一点 from xiaobai import module1 # 也可以导入某个模块的成员进来,可以不用前缀直接使用 from xiaobai.module2 import add_1 通过上述几个,相信你已经有了举一反三的能力,获取对应包的成员或对应包的导入也就不在话下了。我们注意到,这其中的关健就是.这个符号,这个符号能够进入更深的包层级,有了它,即使你有更深层级的子包定义也能顺利导入了。 通过__init__.py文件整合包成员 因为写导入包本身的本质就是会执行__init__.py文件,所以包内的子模块的成员,我们可以在这个文件中编写导入。 我们说一下常见的两种写法的区别(下述不是真正可用的文件代码): # coding:utf-8 # .表示当前模块,这种写法的话相当于将模块导入包名中,调用时依然还是需要使用长长的方式调用 # 比如在__init__.py中这样写导入(该文件不能直接自执行,只能被导入,否则会报错): from . import module1 # test.py中调用时要这样写: import xiaobai print(xiaobai.module1.NAME) # 上述写法很长,我们可以写成这样,在__init__.py文件中: from .module1 import * # 这样在外部就可以用xiaobai前缀来调用module1的全部成员了,在test.py中: import xiaobai print(xiaobai.NAME) 基于前面讲的内容,我们这会儿来补充一下__init__.py文件的内容如下: # coding:utf-8 from .module1 import * from .module2 import * 然后可以在test.py文件中这样写来方便调用: # coding:utf-8 import xiaobai print(xiaobai.NAME, xiaobai.AGE) print(xiaobai.add_1(100)) 这样可以实现在包中方便管理代码,在外部调用时也调用方便。 [!tip] 上述写法比较适用于多个子模块之间没有重名的情况,如果有重名的情况,可能会存在某些成员被覆盖等问题,具体你可以自行测试一下。起名时尽量不要重名,如果非要重名,可以使用之前讲过的导入子模块的方式,而不在初始化文件中做导入。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-16 21:06:16 "},"chapter6/6-7 python3小白课:模块内容查看.html":{"url":"chapter6/6-7 python3小白课:模块内容查看.html","title":"6-7 python3小白课:模块内容查看","keywords":"","body":"python3小白课:模块内容查看 包本质也是模块,本课我们讲的内容也适用于包。 查看模块成员 之前我们讲过,可以使用dir()命令查看包含哪些命令,在这里依然是适用的,参数传入模块名即可,模块需要先行导入。 需要注意的是,使用该命令会把那些包含_下划线的开发者定义的内部成员或特殊方法都给获取到,如果你不希望获取到,可以输入如下命令来获取: [i for i in dir(模块名) if not i.startswith(\"_\")] 使用列表推导式,替换模块名之后即可查看所有非内部成员。 你还可以使用__all__成员来查看开发者想让你知道的有哪些成员,但并非所有模块都有定义该成员,若未定义,可以使用dir()命令或介绍的列表推导式来获取。 查看模块文档 我们多次讲过,一个好的帮助文档是我们必不可少的,定义好之后,可以使用help()命令或__doc__属性来查看帮助文档。 有些python自带的标准库的文档可能不够详实,你可以参考官方的文档: https://docs.python.org/zh-cn/3/library/index.html 你还可以使用如下命令来查看包文档: python -m pydoc -p 8899 在cmd中运行后,会启动一个服务器页面http://localhost:8899/,点击访问你就可以看到你已有的所有包的文档。你也可以在运行改代码之后,在cmd中输入b并回车,打开浏览器访问该页面,按q并回车,退出服务。 查看模块路径 当我们觉得这个模块的代码不错,需要进一步研读python代码了解开发逻辑时(python的源码理论上都是开源的),可以使用__file__属性来查看模块的路径,打开路径中所示的文件即可具体查看代码。一些不错的IDE比如pycharm还支持直接跳转并打开模块所对应的文件,十分方便查看。 比如我们可以这样写: # coding:utf-8 import xiaobai print(xiaobai.__file__) 在python中,还有部分与底层交互的模块不是用python写的,而是用C语言写的,这些程序可能没有__file__属性,请知悉。 单词释义 单词 释义 file 文件 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-09-19 12:36:53 "},"chapter6/6-8 python3小白课:解锁你心仪的三方包.html":{"url":"chapter6/6-8 python3小白课:解锁你心仪的三方包.html","title":"6-8 python3小白课:解锁你心仪的三方包","keywords":"","body":"python3小白课:解锁你心仪的三方包 三方包管理仓库 PyPI(Python Package Index)是python官方的第三方库的仓库,所有人都可以下载第三方库或上传自己开发的库到PyPI。 它的网址为(如果访问比较慢可以寻找一些国内的镜像源站如清华大学包源https://www.lfd.uci.edu/~gohlke/pythonlibs/,或者扶墙): https://pypi.org/ 查看、下载三方包 无需注册,你可以输入你想要查看或下载的包名,搜索详细信息,我们来随意搜索一个,比如做爬虫的一个很不错的三方包requests。输入并点击搜索按钮后会跳转到结果界面: 可以看到有很多很多个搜索结果,可以点击进去最匹配的那个结果。这里看到的2.23.0是最新版本的版本号。 如上图所示,我们进入了包的详情页面,在这里可以看到包的最新版本,底下的pip install requests是使用包管理工具pip来下载包的命令行,可以复制该行放到cmd中执行。关于包管理工具pip,后面我们会再详细讲解。 右上角是现在的版本是否为最新版本以及该版本的发布日期等信息。 在下面正文内容的左侧边栏有一个导航条,如图我们标注出了功能信息,默认进入的是项目描述页,会告诉我们这个包是做啥的,你可以了解一下,该信息由包的开发者提供,如果开发者比较懒,你也可能看不到啥信息。 发行历史部分是查看历史版本时间线用的,如果你需要下载一个指定的历史已发布的版本可以从这里进入。 下载文件部分是展示有哪些资源可供下载的。你可以查看文件类型,适合的python版本,上传日期,哈希值等信息。还可以点击链接进行下载。 比如这里我们看到有两个资源可供下载,.whl文件是wheel文件,轮子的意思,我觉得取的寓意很好,下载了轮子你就不用重复造轮子了。这是python打包中比较新的一种很不错的打包格式,是编译过的包文件,不需要下载代码后自己本机编译,提高了安装的成功率。下载后可以直接通过pip包管理工具安装,网上有些说法是说需要先安装wheel这个三方包才能安装,实测是不需要的。而安装wheel这个库之后可以自己来打包自己的whl文件。 [!tip] 你可以尝试把下载好的whl文件后缀名修改为zip,发现它可以用压缩软件打开,实际它是一个压缩打包文件。 另一种格式是tar.gz格式,这是源码文件压缩格式,在有能用的whl包的时候我们都不太推荐用这种格式,因为有的时候需要你自己本机编译一些原始代码,如果电脑中缺少某些编译库,则会出现各种各样的报错问题,所以不到不得已不使用。 可能还有一些其他你可能见到的格式,你都可以从网上找到对应的安装方法。 上面讲的是到pypi官网去找到包并下载的,这种操作比较适合给一些公司内网(不能连接外网下载)离线安装,或者想看看有些什么包可以用的情况,实际我们在知道要安装什么包的时候,极少会登录pypi官网去下载。 自己贡献三方库 除了使用全球开发者提供的各种各样的三方库之外,你也可以贡献自己的三方库。 只需要在pypi官网注册登录并按照要求上传相关的文件即可。需要注意自己注册的三方库名字不能跟官网中已有的重复即可,这个在注册项目的时候是可以搜索看一下的。 关于这块内容,入门的同学们可以不做掌握,如果大家感兴趣的话,今后在进阶或高级课程中会详细再跟大家讲解。 pip包管理工具 前面我们已经提到了pip这款包管理工具,同很多其他编程语言一样,通过这款工具,我们可以轻松的做到python的三方库的管理、安装、卸载等操作。 这部分我们来着重讲解一下日常常见的使用。 pip工具是一个命令行工具,可以在cmd命令提示符中使用。目前的python安装包通常都会自带pip工具一起安装的,也可以自己去下载安装,可以看一下我们第3课的截图,已经默认安装了。 可以在cmd中输入命令查看是否已安装: pip --version 如果成功弹出版本号,说明安装成功而且可以正常调用。 如果告诉你找不到pip这款工具,首先你可以看一下环境变量中是否已经将python安装目录下的Scripts目录加入了环境变量中,如果也确实加入了,可以重启再看一看。 如果还是不成功,可能你就需要手动安装一下pip了。需要手动安装的同学可以看下,手动安装我们参考官网介绍:https://pip.pypa.io/en/stable/installing/ 首先我们需要戳这个下载相关文件:https://bootstrap.pypa.io/get-pip.py 然后运行命令在线安装pip: python get-pip.py 如果我们保证pip已经安装好了,就来看一下如何使用吧。 我们有如下一些命令来使用: # 通过pip在线安装三方库,如requests,这个命令最常使用,务必牢记 # 它会自动下载适合你目前安装的python的包并安装(如果包依赖于其他包,也会一并下载安装) pip install requests # 查看目前已安装的三方库列表 pip list # 查看目前有哪些三方库有新版本了 pip list -o # 如果pip不是最新版本,pip运行完一些命令时还会经常提醒你升级,升级pip自身的命令(一般也会给出) # 从这个命令我们知道,前面加上python -m也能调用pip相关命令,适用于Scripts文件夹未加入环境变量的情况或升级自身的情况 python -m pip install --upgrade pip # 查看pip的帮助 pip --help # 升级某个三方包,有两种写法(一般来讲功能可以用就无需更新到最新版本,因为可能不兼容) pip install --upgrade 包名 pip install -U 包名 # 卸载某个包 pip uninstall 包名 # 安装一个wheel包,如果已进入whl文件所在路径,直接写完整文件名,否则写完整路径(可加引号) pip install 本地whl文件名 # 安装源码包 pip install 本地tar.gz文件名 # 顺带一提:也可以将该压缩包解压,cmd进入解压后的文件夹,运行如下命令安装: python setup.py install # 当包下载过慢的时候,设置使用国内镜像,你可以网上搜到很多,我们以清华源镜像为例: # 帮助参考:https://mirrors.tuna.tsinghua.edu.cn/help/pypi/ # 临时一次性使用: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名 # 永久使用配置: # 先升级pip最新版(需要>=10.0.0版本) python -m pip install --upgrade pip # 注意不要使用上述网站让你用的这个命令:pip install pip -U,实测卸载pip以后无法安装,会报找不到pip了 # 源设置: pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple # 设置完之后按往常那样安装包即可 # 离线下载包(如果包依赖于其他包,也会一并下载) pip download 包名 # 上述会在cmd当前目录下载包,你可以指定保存目录,更推荐 pip download -d 保存目录 要下载的包名 # 比如下载一个ipython包 pip download -d \"E:\\Programs\\编程开发\\python3\\package\\ipython\" ipython # 将离线下载好的包给不能联网的电脑离线安装: pip install --no-index --find-links=下载的离线包保存目录 包名 # 比如安装ipython的包 pip install --no-index --find-links=\"E:\\Programs\\pythonpackage\\for python3\\ipython\" ipython # 冻结项目所用的三方包(后续我们会讲到虚拟环境,只会冻结虚拟环境中用到的包): # 会将三方包的名称版本号写进requirements.txt这个文件中,供后续换电脑移植快速恢复三方包环境使用 # 约定俗称用requirements.txt,你喜欢也可以改为其他文件名 pip freeze > requirements.txt # 如果新安装的电脑能联网 pip install -r requirements.txt # 如果新安装的电脑无法联网 # 先找台能联网的电脑,批量下载这些三方包 pip download -d \"保存目录路径\" -r requirements.txt # 新电脑批量安装本地离线包 # 这里可能的报错的情况是:当包分py2、py3版本却下载了错误版本时,当python安装的是32位的,但安装包是64位的时。 # 这时候到pypi官网下载正确适合的包即可。 pip install --find-links=\"下载的离线包保存目录\" -r requirements.txt # 搜索三方包 pip search 包名 基本上日常常用的pip命令就这些,大家可以只记住最基本的在线安装命令,因为多数时候我们也只用到这个命令而已。其他的命令,先做一个大致了解,当需要时再回来本次课程查阅即可。 本课涉及到的一些英语单词也比较多,我挑了比较重要的都列举出来了,大家可以看一下加强学习记忆。 当你都记住之后,上面的命令的记忆就基本不成问题了(偷偷告诉你,很多其他编程语言的管理工具的命令行工具的命令是类似的,记住之后对你很有帮助哦)。 单词释义 单词 释义 python package index python包索引,简称PyPI,全球的官方python包仓库 search projects 搜索项目 requests 请求request的复数 pip python的三方包管理工具 install 安装 latest version 最新的版本 navigation 导航 project description 项目描述 release history 发行历史 download files 下载文件 filename, size 文件名,大小 file type 文件类型 wheel 轮子 source 源码 python version python的版本 hashes 哈希值hash的复数 scripts 脚本script的复数 upgrade 升级 uninstall 卸载 setup 安装 config 配置 set 设置,动词 global.index-url global全局的,index-url首页地址 download 下载 --no-index 没有索引,其实我也没太搞懂这个参数用来干嘛的 --find-links 寻找链接,后面给个离线包的目录,告诉pip安装包从该目录下找 freeze 冻结 requirements 要求requirement的复数形式,约定俗称的冻结后保存的文件名 search 搜索 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-11 22:02:54 "},"chapter6/6-9 python3小白课:虚拟环境介绍和安装.html":{"url":"chapter6/6-9 python3小白课:虚拟环境介绍和安装.html","title":"6-9 python3小白课:虚拟环境介绍和安装","keywords":"","body":"python3小白课:虚拟环境介绍和安装 虚拟环境介绍 在本套课程的第1课我就跟大家提到过,如果你所在的公司大多数项目都在使用python2.7,或者你有多个项目需要使用不同版本的三方包时,你使用你喜欢的python版本开发好程序后也无需担心,因为我们有虚拟环境,可以轻松让多版本的python以及多版本的三方包(适用于你的项目的)共存。 有许多可用的虚拟环境包供我们选择,我个人比较喜欢用的是virtualenv这个,你如果喜欢别的,也可以去学习了解。 过去我还不知道还能弄虚拟环境的时候,曾经电脑里安装了python2.7和python3的版本,这时候调用起来这个环境变量的优先级顺序就颇为麻烦,虽然后来是找到办法来解决共存问题,但我又遇到了新的挑战,那就是包管理。默认情况下,你可以通过pip list命令来查看目前已安装的三方包有哪些,我们默认通过pip install 包名的方式安装的包都会直接安装在你的系统python下。同一个包,只允许存在一个,比如你安装了这个包的1.0版本,你就无法使用2.0版本,这在这台电脑只有你自己开发用的情况下还影响不大,无非就是统一用某一个版本开发就好了呗。 [!question] 你要想这样的场景:你的电脑自己平时开发使用的这个包用的是2.0版本。有一天你的老板给你布置了一个项目要求你用这个三方包用跟公司项目统一的1.0版本,这时候你怎么办?难道跟老板说咱不用1.0好嘛用2.0?或者妥协一下卸载自己装的2.0用1.0? 不必那么麻烦,有了虚拟环境,这些包的安装管理都是独立了,你再也没有这样的烦恼了。 同时,每一个虚拟环境还支持不同的python版本,这样python2.7和python3就可以友好共存了,即时你有个项目需要使用python3.8.2,另一个项目却要求python3.6.6,他们都能互不干扰,和平共处,神奇吧? 虚拟环境包安装和初始配置 相信大家已经了解了虚拟环境的高效性了,那么其实我们今后推荐你的系统python安装一个主版本,然后日常开发的每个项目都单独弄一个虚拟环境出来(支持不同python版本和独立的包管理列表),这样你将步入专业的开发之流。 一般来讲,我们在win系统推荐将virtualenv的扩展包一起安装,使用起来更方便,后续我们将基于它们来讲解。 安装很简单,在cmd运行以下命令安装(如果网络连接失败可以多试几次或者扶墙或者镜像安装): pip install virtualenvwrapper-win [!danger] 需要说明的是,目前我的系统python安装的是3.8.2版本,如果你的系统python是2.7版本的,也是支持安装上述包的,然后可以创建python3的任意虚拟环境。 直接安装上述包,它会自动安装virtualenv这个依赖包和其他依赖的三方包等,省时省力。 安装后比如我这里显示的包列表如下: C:\\Users\\xueshanlinghu>pip list Package Version --------------------- ------- appdirs 1.4.3 distlib 0.3.0 filelock 3.0.12 pip 20.0.2 setuptools 46.1.3 six 1.14.0 virtualenv 20.0.18 virtualenvwrapper-win 1.2.6 完成后,我们还需要去手动配置一下环境变量,打开系统的环境变量配置。 新建一个变量名为WORKON_HOME的系统变量,变量值写你未来想用来存放各个虚拟环境的文件夹,你可以自定义: 完成后确定保存,重启计算机一下。 重启后,打开一个新的cmd窗口。输入命令workon,这时就会列举出你在刚才系统环境变量时设定的变量值那个文件夹下的所有虚拟环境了。由于目前我们还没有创建任何一个虚拟环境,所以目前列表为空。 在下一节课我将教会大家虚拟环境的创建、删除、切换激活、取消激活等等高端操作,我们还支持某虚拟环境指定python版本地创建,记得来学习哦~ 单词释义 单词 释义 virtualenv virtual虚拟的,env,environment环境的简写 virtualenvwrapper-win 前面部分讲过了,不赘述,wrapper包装纸,封皮,封套,这里理解为封装扩展包,win,windows平台,linux平台对应应安装的包为virtualenvwrapper workon_home work on合并词,向...做工作,我理解为在哪个路径下工作,home家 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-11 22:03:30 "},"chapter6/6-10 python3小白课:虚拟环境使用.html":{"url":"chapter6/6-10 python3小白课:虚拟环境使用.html","title":"6-10 python3小白课:虚拟环境使用","keywords":"","body":"python3小白课:虚拟环境使用 上节课我们安装好了虚拟环境,这节课我们来教会大家基本的使用,关于其他使用命令,日常不常用的,我就不讲解了,讲多了大家也记不住。 接着上节课我们打开了一个cmd窗口对吧,目前还是没有任何虚拟环境的。 创建虚拟环境 mkvirtualenv test 回车,就创建好了,你可以使用workon查看到生成了一个名为test的虚拟环境,并且直接激活进入了该虚拟环境。 这里mkvirtualenv就是创建新的虚拟环境的命令,你记住mk即可,应该是英文单词make制造。后面跟随的是空格和虚拟环境的名字,它会在之前的WORKON_HOME路径下创建一个以这个名字命名的文件夹,所以你的名字也别太花哨了,文件夹名不支持的字符不要作为名字哦~比如我们这里就是名字为test,到资源管理器中查看该路径,确实该文件夹已经创立。 这种命令的写法默认会使用你当前的系统python的版本创建一个虚拟环境。 像这种创建方法你可以直接进入到新虚拟环境中,大家可以看到在上图中命令提示符最后一行的最左侧多了(test)这样的标识,这就是已进入虚拟环境的标志。在虚拟环境进入后,我们可以输入python进入当前虚拟环境版本的python shell,也可以使用python py文件名或pip命令来使用虚拟环境。这时你若使用pip install 包名命令,安装的包只会存在于虚拟环境,不会安装到系统的python环境,这就能让项目的三方包环境非常整洁干净,未来你需要看一下这个项目用了哪几个三方包,版本号是多少的时候就会极其方便。 [!note] 如果你感兴趣,可以到虚拟环境的存放目录,看一下虚拟环境跟普通已安装好的python有什么区别。 可以发现,其实就是将已安装的python进行虚拟化,复制一份,文件夹也做了一些优化,让它可以作为独立环境运行。 退出已激活的虚拟环境 [!question] 创建好了虚拟环境,怎么退出呢? deactivate activate是激活的意思,加上否定前缀就是不激活咯,就是退出虚拟环境了,而activate也是一个激活的命令,后面我们会讲到。 如图,命令提示符最后一行的最左侧恢复了正常。 激活或切换虚拟环境 如上面的截图例子所示,我们的当前目录在C:\\Users\\xueshanlinghu这个路径下,我们可以切换当前工作目录到你要激活的那个虚拟环境目录下的Scripts文件夹下,如E:\\ProgramFiles\\virtualpython\\test\\Scripts,在这里我们可以运行 activate 即可激活虚拟环境。 但我一般很少这样操作。还记得我们上节课学习过的可以通过workon命令查看当前有多少个虚拟环境吗,它会把所有虚拟环境的名字罗列出来。你如果知道你要进入哪个虚拟环境的名字,可以在任意工作目录下输入命令: workon test 这样我们可以更轻松进行虚拟环境的激活了,test这个虚拟环境名你可以换成你的。通常推荐大家这样用。 顺便,我们来看一下pip list和pip --version的运行效果: 可以看到,都是单独的。 删除虚拟环境 [!question] 当某虚拟环境不准备再使用了怎么办? 那就删除呗。 你可以到虚拟环境的文件夹将该虚拟环境文件夹直接删除即可。 我个人一般会用命令删除: rmvirtualenv test 这样就可以把test这个虚拟环境删除了。其实就是前面加了rm,应为remove移除的意思,很好理解和记忆。 安装其他版本的python的虚拟环境 这里我们的系统环境python是3.8.2版本,我们拿安装python2.7.18和python3.6.6版本的虚拟环境为例跟大家做讲解,其他的可以举一反三。 安装包下载(我也会在课程中提供给大家,这里均为64位的安装包为例): python3.6.6:https://www.python.org/ftp/python/3.6.6/python-3.6.6-amd64.exe python2.7.18:https://www.python.org/ftp/python/2.7.18/python-2.7.18.amd64.msi python3.6.6虚拟环境创建 安装很简单,跟之前学习的差不多,需要注意的是,不要选择添加到环境变量就可以了。 这里比如我安装在E:\\ProgramFiles\\virtualpython\\purepython\\python3.6.6目录下。 安装完成后复制一份该文件夹到当前目录下。复制后,就可以到系统程序与功能-卸载或更改程序那里,将python3.6.6版本卸载掉了,这样可以让系统不那么乱,更绿色。卸载后,将刚才备份的文件夹重命名跟复制前python3.6.6一样。 完成后即可在cmd输入命令创建了,例如: mkvirtualenv -p \"E:\\ProgramFiles\\virtualpython\\purepython\\python3.6.6\\python.exe\" py36 mkvirtualenv --python \"E:\\ProgramFiles\\virtualpython\\purepython\\python3.6.6\\python.exe\" py36 [!tip] 上面两种方法均可以创建,任选一种即可,我个人喜欢第一种。-p参数后面跟上你安装的其他版本python的python.exe解释器的绝对路径,如果路径中没有空格可以不加引号,如果有需要加上引号,我建议你都加上就好了。写完后再写上需要创建的虚拟环境名称即可。 你看,成功了! python2.7.18虚拟环境创建 由于安装包是msi的后缀,所以稍微跟python3的有一点点小区别。 安装时注意点我就不多说了,参考我们之前安装python的时候,需要注意的是不要选择添加到环境变量,默认就是不选的,按默认的就行: 这里我安装到了E:\\ProgramFiles\\virtualpython\\purepython\\python2.7.18这个文件夹下。复制一下这个文件夹。 接下来这一步很重要,你需要到C:\\Windows\\System32这个目录,搜索python27.dll这个文件并拷贝到另一个地方备份。 然后到系统程序与功能-卸载或更改程序那里将python2.7.18版本卸载了,卸载完成后,将刚才复制备份的文件夹修改回python2.7.18这个文件夹名。 将python27.dll这个文件还原到C:\\Windows\\System32这个目录。 这样,绿色版的python2.7.18就制作好了。 你可以输入命令来创建一个python2.7的虚拟环境了: mkvirtualenv -p \"E:\\ProgramFiles\\virtualpython\\purepython\\python2.7.18\\python.exe\" py27 可以看到,确实使用了python2.7.18的版本。 [!tip] 在python2语法中,打印输出使用的是print 要打印的内容这样的写法,而在python3中,变成了print(要打印的内容),你可以很好地辨别用的是python2还是python3,请知悉。 冻结项目所用的包 之前我们在学习解锁心仪的三方包的时候,学习过可以使用pip freeze > requirements.txt命令来冻结所用到的三方包的情况,我们来举个例子。 我们分别在cmd中输入下面的命令: workon py36 # 切换py36虚拟环境 pip install requests # 安装requests三方包及相关包 pip list # 查看目前的pip列表 pip freeze > requirements.txt # 冻结目前所用的所有三方包保存到文件 type requirements.txt # cmd中打开文本文件并打印输出所有内容 运行结果如下: Microsoft Windows [版本 10.0.18363.778] (c) 2019 Microsoft Corporation。保留所有权利。 C:\\Users\\xueshanlinghu>workon py36 (py36) C:\\Users\\xueshanlinghu>pip install requests Collecting requests Downloading requests-2.23.0-py2.py3-none-any.whl (58 kB) |████████████████████████████████| 58 kB 363 kB/s Collecting certifi>=2017.4.17 Using cached certifi-2020.4.5.1-py2.py3-none-any.whl (157 kB) Collecting chardet=3.0.2 Using cached chardet-3.0.4-py2.py3-none-any.whl (133 kB) Collecting urllib3!=1.25.0,!=1.25.1,=1.21.1 Using cached urllib3-1.25.9-py2.py3-none-any.whl (126 kB) Collecting idna=2.5 Using cached idna-2.9-py2.py3-none-any.whl (58 kB) Installing collected packages: certifi, chardet, urllib3, idna, requests Successfully installed certifi-2020.4.5.1 chardet-3.0.4 idna-2.9 requests-2.23.0 urllib3-1.25.9 (py36) C:\\Users\\xueshanlinghu>pip list Package Version ---------- ---------- certifi 2020.4.5.1 chardet 3.0.4 idna 2.9 pip 20.0.2 requests 2.23.0 setuptools 46.1.3 urllib3 1.25.9 wheel 0.34.2 (py36) C:\\Users\\xueshanlinghu>pip freeze > requirements.txt (py36) C:\\Users\\xueshanlinghu>type requirements.txt certifi==2020.4.5.1 chardet==3.0.4 idna==2.9 requests==2.23.0 urllib3==1.25.9 (py36) C:\\Users\\xueshanlinghu> 换一个项目,所用的包不同,则你可以再创建一个新项目的虚拟环境,在里面任意折腾,当不需要时,删除该虚拟环境即可。 我们退出虚拟环境,再看一下系统python的pip list有没有什么变化,结果如下: (py36) C:\\Users\\xueshanlinghu>deactivate C:\\Users\\xueshanlinghu>pip list Package Version --------------------- ------- appdirs 1.4.3 distlib 0.3.0 filelock 3.0.12 pip 20.0.2 setuptools 46.1.3 six 1.14.0 virtualenv 20.0.18 virtualenvwrapper-win 1.2.6 C:\\Users\\xueshanlinghu> 可以看到,只有之前安装virtualenv的一些相关的包,清清爽爽,干干净净。 单词释义 单词 释义 mkvirtualenv mk,make创建、制造的简写,virtualenv虚拟环境 deactivate 让...停止工作,就是退出激活的意思 activate 激活 rmvirtualenv rm,remove移除的简写,virtualenv虚拟环境 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-11 22:05:30 "},"chapter7/":{"url":"chapter7/","title":"七、类和对象","keywords":"","body":"七、类和对象 过去我们写一个单独的函数,是一种面向过程的编程方法,即实现某个函数,就可以解决某个过程的问题了。随着编程技术的进一步发展,通过将现实事物抽象成对象的方式,通过封装技术,可以让人像搭积木一样快速开发出一个全新的复杂系统。 面向对象编程是一种编程范式,它可以最大限度地提高程序代码的可复用性和可维护性、可扩展性,之前我们学习过列表、元组等各种类型,而面向对象编程可以进行类的自定义,写出你的自定义类型。 面向对象的编程思想众多的编程语言都有,学会了本章的内容,其他的编程语言面向对象的思想你也可以很容易掌握。 想知道类和对象都是什么吗?快来进入我们本章的学习吧! 相对之前的内容来说,本章内容难度较大,我们选择了一些入门需要了解掌握的知识跟大家教学(进阶内容后续我们会在后续课程中继续精进)。如果你一遍听不懂是很正常的,我也是反复看了无数遍才掌握了解的,如果听不懂,再回来重新学习几遍就可以了。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-04-22 20:42:01 "},"chapter7/7-1 python3小白课:一节课搞懂面向对象.html":{"url":"chapter7/7-1 python3小白课:一节课搞懂面向对象.html","title":"7-1 python3小白课:一节课搞懂面向对象","keywords":"","body":"python3小白课:一节课搞懂面向对象 在学习python的类(class)和对象(object)之前,我们先来搞懂什么是面向对象编程(OOP)(有些同学会戏称为面向对象(你家的男女朋友)编程,开个玩笑,能记住最好)。 因为概念相对比较抽象,咱一板一眼的解释大家肯定看不懂,所以我思虑再三,也结合了一些网络资料的解释,用最通俗易懂的生活中的故事来跟大家解释面向对象的思想以及面向对象的三大特性——封装(Encapsulation)、继承(Inheritance)、多态(Polymorphism)。 本例中的图片源于网络并做了一定的PS,仅供学习说明使用。 类的封装 冬天到了,屋里好冷啊,这时候我们就需要一个暖风机了。暖风机插上电之后就可以送暖风了。 这时候我们就有一家生产暖风机的厂商,他们生产的暖风机如图所示: 从上图的特点,我们类比面向对象的概念,暖风机这类产品它的生产规范是固定好的,有上图打勾的三个特点,这一类产品,我们称之为暖风机类,这个类里面可以定义一些东西,比如: 类的成员变量:机身、加热片 类的成员属性:机身是红色的 类的成员方法:可以通过温控旋钮方法来启动关闭暖风机,传入不同的参数还可以有不同档位的温度(是不是有点像函数?) 类是一系列特征的抽象形式,暖风机类仅能定义规范,但不是实实在在到你手中的产品。所以我们需要使用对象来将类实例化,比如这个工厂参照着这样的标准,生产了1000台暖风机,如果你编个号,那就是暖风机1号、暖风机2号…… 这些具体的产品,就是我们所说的对象,就是抽象类实例化后的产物。 [!note] 如果这个例子你不好理解,我补充一个小例子。人类是类,是抽象的,但我们许许多多的不同的人就是人类实例化后的产物,所以我们是对象,也叫一个类的实例。 类里面,我们可以定义一些变量、属性、方法等,方法就类似我们平常说的函数,可以执行一系列的动作等,但只有这个类才拥有这些方法,外部需要调用该类的方法,比如对类进行实例化。比如理论上每个人都会走路这个方法,需要实例化到每个人,才能调用每个人的走路方法。 将变量、属性、方法等定义到某个类中,仅有这个类或类的实例(也就是对象)才能访问它们,它可以将内部的一些实现细节隐藏起来,跟外界隔绝,如果各种实例的方法实现均需要修改,则修改类内部的成员定义即可,维护起来也是颇为方便的。 这,就是类的封装。 类的继承 有一天,这个暖风机工厂的老板说,暖风机上如果有摇头的功能,那些暖风可以不一直吹着某个位置,肯定能卖得更好!所以要求工厂生产一种全新的暖风机,我们称之为会摇头的暖风机。 这时候,工厂有如下选择: 设计一个全新的会摇头的暖风机 在现有暖风机的基础上,增加一个按钮,按下去就摇头,再按一下就固定 [!question] 从节约成本的角度来说,你会选择哪种方案? 显然,选择第二种方案更加节约成本,因为它只是增加了一个按钮,我们可以将它设计为暖风机的新方法。 这时候我们直接在之前的暖风机类上改设计的代码吗?不对,因为暖风机类我们之前已经定义过,就是具有之前那几个特征的普通暖风机。 这时,我们在代码中可以使用继承的方法,将新的会摇头的暖风机类继承自原来的暖风机类,这样它就默认拥有了之前暖风机类的特点、方法等。 继承后,我们在新的会摇头的暖风机类中额外定义一个新的方法:摇头,即可。 实现继承的类会摇头的暖风机类称之为继承类或子类,被继承的类暖风机类被称为父类、基类或超类。我个人多数会叫父类、子类这样的叫法。继承类会自动拥有基类的所有特征成员,子类更像是父类的进一步扩展,这里好像颇有青出于蓝而胜于蓝之意,代码维护起来也颇为方便。 这,就是类的继承。 类的多态 基于封装和继承的特性,面向对象还能延伸出多态的特性来,简单来说,就是不同的对象对于同样的方法可以呈现出多种不同的状态。 我们举例说明,还是接着上面的例子。 夏天到了,暖风机卖不动了,即使工厂的暖风机能360°摇头估计销量也不太行了,天气太热了,当然还是空调(落地那种)比较好。 这时候,我们就不说方案了,直接选择继承之前会摇头的暖风机类来进一步开发比较省事省钱,新的类名为会摇头的冷风机类。 但是这机身里面放的是啥?是加热片!那怎么能制冷呢?这时候我们可以重写父类里面的成员和方法,比如变量修改为机身+制冷片,旋钮的方法修改为调节旋钮可以控制冷风的大小。我们改成下图这样: 同样是调用同名的成员变量(机身组成)和成员方法(温控旋钮),我们的冷风机却展现出截然不同的功能。 [!note] 再补充一个小例子,一般的鸟类都会飞,鸵鸟也是一种鸟,继承了鸟类这个类,但它不会飞,所以它内部改写了会动翅膀这个方法的实现,普通的鸟实现下来就是飞起来了,而鸵鸟的代码实现却是飞不起来的。 这,就是类的多态。 单词释义 单词 释义 class 类 object 对象 OOP Object Oriented Programming面向对象程序设计 Encapsulation 封装性 Inheritance 继承性 Polymorphism 多态性 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-11 22:07:13 "},"chapter7/7-2 python3小白课:定义类和实例化对象.html":{"url":"chapter7/7-2 python3小白课:定义类和实例化对象.html","title":"7-2 python3小白课:定义类和实例化对象","keywords":"","body":"python3小白课:定义类和实例化对象 搞懂面向对象之后,我们来开始讲python中的类如何定义,首先我们需要先定义类,才能通过类来实例化对象。 在python中,定义类的语法如下: class 类名: 执行语句、类变量、类方法等 我们可以看到,定义一个类的关键字为class,类名的命令跟之前变量命名差不多,但一般约定俗成,类名是一个或多个有意义的单词连缀而成的,中间没有分隔符,每个单词的首字母大写,其他字母全部小写,比如XiaoBai。 类之内可以写一些执行语句、定义变量、定义方法(需要注意该缩进的地方缩进),定义方法使用的也是def关键字,跟平时定义一个函数差不多,但形参定义时有一点小小的不同,这个后面会讲解。 如果类中没有任何内容,或者暂时不添加代码内容,你可以使用pass关键字来先占位。 我们来看一个小例子来讲解细节: # coding:utf-8 class Student: \"\"\"这个地方可以定义类的帮助文档\"\"\" # 定义类变量 sex = \"男男男\" # 定义构造函数 def __init__(self, name, age=18, sex=\"男\"): # 实例的变量,区别于类变量 self.name = name self.age = age self.sex = sex # 定义一个其他方法 def info(self): print(Student.sex) print(\"姓名:{},年龄:{},性别:{}\".format(self.name, self.age, self.sex)) # 查看帮助文档 help(Student) # 实例化对象 s = Student(\"小白\", 19) s.info() print(s.name, s.age, s.sex) # 可以赋值 s.name = \"小黑\" s.info() # 调用类变量需要加上类名 print(Student.sex) 首先我们使用了class关键字定义了一个Student类,里面可以定义类帮助文档、类变量和方法,我们可以发现,定义的类变量在调用的时候需要加上类名。 类中一般会定义一个__init__的构造函数,它也是python系统中内置的特殊方法。这个函数在实例化对象的时候会自动调用,通常一个类会包含这个函数,并且会在这个函数中初始化一些实例变量。首先我们可以注意到每一个方法的第一个形参都是self,即使在没有参数应传入的方法中也是如此,这是类的方法跟普通函数的定义的不同之处。为什么要这样呢?类的方法一般会通过实例化后的对象进行调用,self表示调用它的对象本身,调用方法时对象会自动绑定到第一个形参中去,调用时从第二个形参开始传递参数即可。这是约定俗成的,你记住就行,更深入的探究可以结合后面的课程或者查阅资料来理解。 [!tip] 实际也不一定要用self可以用别的,在类中统一即可,但约定俗称用self,这样具有最好的可读性,在某些IDE中也能自动进行处理。 我们需要注意,实例变量跟类变量是不同的。所以self.sex和sex是不同的,类变量一般在方法之外定义,一般来讲不同的实例会共用一份,可在外部赋值修改,使用类名来调用它,如Student.sex,直接用sex不行。而实例变量的话是像self.sex这样的,一般在构造函数中创建。我们可以创建多个实例,每个实例都可以设定自己的sex值。调用时使用实例名.sex调用,比如我们的实例名为s,那就是s.sex即可。如果有需要,我们也可以在外部代码添加实例变量,比如在外部代码中增加一句s.nickname = \"小白白\",这样这个实例就多了一个新的实例变量了。 在实例化对象的时候,我们可以自行设定一个实例名(变量),初始化之后,就可以使用该实例名来调用该实例下的实例变量和方法了。比如这里我们使用s作为实例名。创建实例之后,我们可以给取现有的实例变量的值,也可以赋值。甚至还可以定义新的实例变量,但使用范围仅限于该实例。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-09-19 12:38:52 "},"chapter7/7-3 python3小白课:了解实例方法.html":{"url":"chapter7/7-3 python3小白课:了解实例方法.html","title":"7-3 python3小白课:了解实例方法","keywords":"","body":"python3小白课:了解实例方法 首先我们来看一下例子: # coding:utf-8 class Student: \"\"\"这个地方可以定义类的帮助文档\"\"\" # 定义类变量 sex = \"男男男\" # 定义构造函数 def __init__(self, name, age=18, sex=\"男\"): # 实例的变量,区别于类变量 self.name = name self.age = age self.sex = sex # 定义一个其他方法 def info(self): print(Student.sex) print(\"姓名:{},年龄:{},性别:{}\".format(self.name, self.age, self.sex)) s = Student(\"小白\") # 调用实例方法 s.info() 如上代码,我们可以看到,在类之中我们可以定义一些这个类的实例能做的一些事情,比如这个info方法就是每一个实例拥有的方法,实例创建之后,就可以调用这个实例的实例方法了,你也可以定义实现一些其他的事情,是不是很简单呢? Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-05-23 20:59:58 "},"chapter7/7-4 python3小白课:用property函数定义属性.html":{"url":"chapter7/7-4 python3小白课:用property函数定义属性.html","title":"7-4 python3小白课:用property函数定义属性","keywords":"","body":"python3小白课:用property函数定义属性 除了我们可以直接设定实例变量之外,我们在定义类的时候,还可以定义一些获取、设置等的专门的方法,将这些方法放到property参数中,可以让实例变量拥有这些属性。 这么说可能大家听得不是太明白,我们先来看一眼property函数(属性)的语法格式和说明,再来举例子: property函数的语法格式为: property(fget=None, fset=None, fdel=None, doc=None) 这里四个参数,fget表示获取方法,fset表示赋值方法,fdel表示删除属性时调用的方法(使用del 实例名.属性名可以删除属性,比较少用),doc表示说明文档,是一个字符串。你可以传入0-4个参数,如果没有传入的参数,表示不允许对那个属性做那样的事。比如传入0个参数,表示该属性既不能读,也不能写;又比如传入1个参数,表示为只读属性。以此类推。 下面我们直接来看一个例子来理解吧。 # coding:utf-8 class Student: def getname(self): return self.name def setname(self, name): print(\"进行了设置\") self.name = name this_name = property(getname, setname) s = Student() s.this_name = \"小白白\" print(s.this_name) 如上的代码,我们设定了一个可以读写的属性this_name,为了跟name进行区别,我增加了前缀,后续在进行设置和获取的时候会分别调用setname(赋值时会调用那个我额外补的print函数,你也可以把print函数改成一些赋值前的前置验证啊检查啊什么的,达到不符合条件就无法赋值的目的)和getname方法。 单词释义 单词 释义 property 性质,属性 get 获取 set 设置 del delete删除的简写 doc document文档的简写 this 这个,这一个 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-05-23 21:52:43 "},"chapter7/7-5 python3小白课:封装和隐藏.html":{"url":"chapter7/7-5 python3小白课:封装和隐藏.html","title":"7-5 python3小白课:封装和隐藏","keywords":"","body":"python3小白课:封装和隐藏 封装(Encapsulation)是面向对象的三大特征之一,它将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。 我们在上一节课的小案例中可以通过property函数来实现小小的封装和隐藏,让某些实例变量的设定和获取可以通过特定的方法进行。 但仅仅是这样隐藏还是不够的,这节课咱们来教大家黑科技,那就是说可以在实例变量或者实例方法前面加两个_也就是__就可以实现变量或者方法的隐藏。 我们来看个例子: # coding:utf-8 class Student: def __hide(self): print(\"我是隐藏的方法,你能调用我吗?\") def getname(self): return self.__name def setname(self, name): print(\"进行了设置\") self.__name = name this_name = property(getname, setname) s = Student() s.this_name = \"小白白\" print(s.this_name) s.__name = \"小黑黑\" print(s.this_name) print(s.__name) 在这个例子中,我们设定了一个隐藏方法(这个后面讲),然后我们发现即使修改隐藏变量__name的值,this_name属性的值也不会被修改。 其实我们只需要关注this_name这个属性就好了,它的好处显而易见,那就是可以保证对于这个属性的修改是安全的,可以在赋值的时候增加一些逻辑控制。 好了,接下来我们再尝试一下在上述代码的基础上添加如下代码: s.__hide() 运行后发现报错:AttributeError: 'Student' object has no attribute '__hide'。 这意思就是说找不到这个方法,这个方法明明叫做这个呀,为什么报错呢? 这就是因为它被隐藏了!不能被直接调用。这也被称为变为类的私有方法。 但真的想调用怎么办?其实也是有办法的。 我们只需要改成这样: s._Student__hide() 即可正常调用了。仔细研究一下,其实这是python设计者跟我们玩的一个小把戏,调用这种隐藏的方法的时候,需要在方法名前面,还加上一个_下划线和类名,比如我这里的_Student,再接上方法名即可。 从上述的表达我们可以知道,在python的类中其实也没有提供真正的隐藏机制(变成私有方法的机制),所有成员都是默认公开的,但能有这个小把戏也挺好的,不是么? 单词释义 单词 释义 hide 隐藏 AttributeError 属性错误 attribute 属性 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-09-19 12:40:46 "},"chapter7/7-6 python3小白课:类的继承和多继承.html":{"url":"chapter7/7-6 python3小白课:类的继承和多继承.html","title":"7-6 python3小白课:类的继承和多继承","keywords":"","body":"python3小白课:类的继承和多继承 继承也是面向对象的三大特征之一,它是软件实现复用的重要手段,所以一定要学好,在python中,类可以直接继承自其它的0个到多个类。 继承的语法如下: class 子类类名(父类类名1, 父类类名2, ...): # 下面是类定义的部分 对比类的定义,其实继承很简单,就是在类名后面加上括号,里面写上继承自哪些父类即可。继承后,可以拥有父类的各种方法等,无需再重新定义一次,很方便,这样可以实现复用。 [!tip] 之前的课程中我们学习的类的定义都是没有定义父类的,他们都有一个默认的父类object,所以object类是所有类的父类。 接下来我们来看一个简单的例子: # coding:utf-8 class Fruit: def info(self): print(\"我是一个水果,我的颜色是%s\" % self.color) class Food: def taste(self): print(\"我是一种食物,不同的食物味道不同\") class Banana(Fruit, Food): pass # 创建Banana香蕉对象并使用 b = Banana() b.color = \"yellow\" # 调用实例方法 b.info() b.taste() 我们运行后会发现,即使我们对Banana这个类里面啥都没有定义,但因为它是继承自水果、食物这俩父类,所以可以赋值里面的实例变量,也可以调用父类里面的方法,这就是类的继承在python中的小例子。 [!danger] 需要注意的是,很多其他编程语言不支持多继承,而python是支持的,在没有必要的情况下,尽量使用单父类继承,这样逻辑比较清晰,也不容易出现莫名其妙的错误。 你还需要想到的一点是,如果进行多继承时,多个父类之中有同名方法怎么办?事实是,排在前面的父类中的方法会屏蔽排在后面的父类中的同名方法。我们来看个小例子: # coding:utf-8 class Fruit: def info(self): print(\"我是一个水果,我的颜色是%s\" % self.color) class Food: def info(self): print(\"我是一种食物,不同的食物味道不同\") class Banana(Fruit, Food): pass # 创建Banana香蕉对象并使用 b = Banana() b.color = \"yellow\" # 调用实例方法 b.info() 可以看到,虽然我们继承的两个父类都有info这个方法但是因为顺序原因,后面的那一个info方法并没有被执行。 [!danger] 上述的例子都是最终继承下来的子类是不定义任何方法的,事实上,我们也可以在子类中定义子类特有的方法,比如香蕉相比水果和食物,可能还有自己的特性,比如需要剥皮来吃等,这样可以在子类中定义自己的特有方法,而不影响父类。这一点我们就不展开讲了,你理解成子类可以扩展(extend)父类即可。 单词释义 单词 释义 object 对象 Fruit 水果 Food 食物 color 颜色 taste 味道,滋味 Banana 香蕉 yellow 黄色 extend 扩展 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-05-23 23:25:34 "},"chapter7/7-7 python3小白课:重写父类方法和使用super函数.html":{"url":"chapter7/7-7 python3小白课:重写父类方法和使用super函数.html","title":"7-7 python3小白课:重写父类方法和使用super函数","keywords":"","body":"python3小白课:重写父类方法和使用super函数 重写父类方法 子类可以继承父类的方法,但有的时候,子类可能在某些行为上有自己的表现形式,这时候就要重写父类的方法。 咱举个简单的例子,我们知道鸟类有飞翔的技能, 鸡也是一种鸟类,那么鸡理论上也继承了飞翔的技能。但实际表现呢?鸡只能扑棱扑棱翅膀,是不能像其他鸟内一样飞的很高的,所以这时候就要重写鸡的飞翔的方法。 [!tip] 鸡属于鸟类。 解析:鸟类在动物分类上属于一个“纲”——“鸟纲”。鸟纲动物就是我们俗称的鸟类。 鸡属于鸟纲,雉科家禽,据研究,鸡的听觉器官(内耳、外耳)对可听声有很好的敏感性。鸡栖息地面,除耳朵外,它的腿部还具有灵敏的振动感受器,震前可能感受到地声,出现行为异常。 所以鸡是鸟类。 因此我们可以看一下如下示例代码: # coding:utf-8 class Bird: def fly(self): print(\"我在天空,自由飞翔\") class Chicken(Bird): def fly(self): print(\"我在地面,扑棱扑棱翅膀\") a = Chicken() a.fly() 重写父类方法会覆盖掉父类原来的代码,就像示例写的那样。 使用super函数调用父类的构造方法 python规定:如果子类重写了父类的构造方法,那么子类的构造方法必须调用父类的构造方法。我们可以采用super()函数来调用父类的构造方法。 比如我们看这样一个例子: # coding:utf-8 class Bird: def __init__(self): self.name = \"鸟类\" def fly(self): print(\"我在天空,自由飞翔\") class Chicken(Bird): def __init__(self): pass def fly(self): print(\"我在地面,扑棱扑棱翅膀\") a = Chicken() print(a.name) 我们可以看到在这个简单的例子中,子类重写了父类的__init__这个构造方法,但里面什么内容也没写,这样一运行,会报错,实际没有继承和运行父类的构造方法。 但如果我们把代码改成这样: # coding:utf-8 class Bird: def __init__(self): self.name = \"鸟类\" def fly(self): print(\"我在天空,自由飞翔\") class Chicken(Bird): def __init__(self): super().__init__() def fly(self): print(\"我在地面,扑棱扑棱翅膀\") a = Chicken() print(a.name) 添加了这一句:super().__init__()。这样用super()函数指代父类来调用父类的构造方法,这样再执行就可以获取到父类初始化好的name信息了。 这样的应用还可以应用在从多个父类继承的情况下,如果多个父类都写了自己的构造方法,那么默认情况下子类只会调用第一个父类的构造方法并初始化(因为排在前面),这时候就可以写一个子类的构造方法,来分别调用父类的构造方法了,这样多个父类继承也都能初始化到了。大家感兴趣可以自己深入再研究一下。初学阶段掌握到这里就ok了。 单词释义 单词 释义 Bird 鸟,鸟类 fly 飞,飞翔 Chicken 鸡 super 超级 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-12 21:29:03 "},"chapter7/7-8 python3小白课:类的多态性.html":{"url":"chapter7/7-8 python3小白课:类的多态性.html","title":"7-8 python3小白课:类的多态性","keywords":"","body":"python3小白课:类的多态性 多态性是面向对象的三大特征之一,多态性常常是基于继承性得来的,它的概念是,当同一个变量在调用同一个方法的时候,可能会呈现出不同的行为,具体呈现的行为由这个调用的变量所代表的对象来决定,这就是类的多态。 咱们用通俗的例子来讲,咱们有龟和兔两种动物,我们就当做两类吧。这时候龟类和兔类都有赛跑这样的行为,我们可以分别把龟类和兔类赋值给同一个变量,比如a,分别调用a的赛跑这个方法,他们的呈现行为是不同的,龟类是四个小爪子慢慢的爬过去的,兔类呢是四个小短腿一跳一跳跑过去的,这就是所谓的多态(Polymorphism)。 那么多态性有啥用呢? 我们来看一个小小的例子来理解一下: # coding:utf-8 class Run: def run_machine(self, product): print(\"--开始运行--\") product.run() class 烧水壶: def run(self): print(\"烧水咯\") class 烧茶壶: def run(self): print(\"烧茶咯\") a = Run() a.run_machine(烧水壶()) a.run_machine(烧茶壶()) 可以看出,多态是一种非常灵活的编程机制,这时候a这个对象可以不变,只需要变传入的参数对象(如烧水壶、烧茶壶)即可,参数对象都有run方法,所以在执行run_machine()方法的时候可以呈现不同的行为表现,这大大提高了run_machine()方法的灵活性。 [!tip] 前面的课程中我们讲过python3的变量支持中文,这里也试验了一把。 单词释义 单词 释义 Polymorphism 多态性 run 运行,跑 machine 机器 product 产品 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-11 23:29:15 "},"chapter7/7-9 python3小白课:可以被枚举的类.html":{"url":"chapter7/7-9 python3小白课:可以被枚举的类.html","title":"7-9 python3小白课:可以被枚举的类","keywords":"","body":"python3小白课:可以被枚举的类 有时候,我们需要定义一个类似下拉列表条目的东西,这个类是可以被枚举的,比如一年只有四个季节,一年只有12个月等,它们也可以弄成一个类供选择和调用。 直接创建枚举类 来看看小例子吧: # coding:utf-8 import enum Season = enum.Enum('Season', ('SPRING', 'SUMMER', 'FALL', 'WINTER')) 这里我们定义了一个季节枚举类,有四个季节,用了内置enum包中的Enum函数来构造,第一个参数为枚举类的类名,第二个参数为一个元组,每个元素就是每个枚举值。 访问枚举类中的成员 定义枚举类之后,每个成员都有name和value两个属性,name为枚举值的名称,value为枚举值的序号(从1开始)。 如上述的定义季节的例子,我们就可以这样查看: # coding:utf-8 import enum Season = enum.Enum('Season', ('SPRING', 'SUMMER', 'FALL', 'WINTER')) print(Season.SUMMER) print(Season.SUMMER.name) print(Season.SUMMER.value) 也可以根据名称或者序号来访问: # coding:utf-8 import enum Season = enum.Enum('Season', ('SPRING', 'SUMMER', 'FALL', 'WINTER')) print(Season['FALL']) print(Season(1)) 还可以通过__members__属性来获取,这个属性可以返回一个字典dict,可以进行解析显示,看例子: # coding:utf-8 import enum Season = enum.Enum('Season', ('SPRING', 'SUMMER', 'FALL', 'WINTER')) print(Season.__members__) for name, member in Season.__members__.items(): print(\"%s => %s, %s\" % (name, member.name, member.value)) 为枚举类定义额外方法 通过继承Enum来派生枚举类,可以给新的枚举类定义特有的方法,这是高级定义枚举类的方法: # coding:utf-8 import enum class Season(enum.Enum): # 先指定value值,不一定要是数字 SPRING = '春' SUMMER = '夏' FALL = '秋' WINTER = '冬' # 可以定义特有的方法 def get_month(self): if self.value == '春': month = \"1-3月\" elif self.value == '夏': month = \"4-6月\" elif self.value == '秋': month = \"7-9月\" elif self.value == '冬': month = \"10-12月\" print(\"这是一个在【%s】的季节\" % month) # 用各种方式来查看这样定义的结果展现 print(Season.WINTER) print(Season.WINTER.name) print(Season.WINTER.value) Season.FALL.get_month() for name, member in Season.__members__.items(): print(\"%s => %s, %s\" % (name, member.name, member.value)) 可以看到,通过这样的高级枚举,我们可以定义特有的方法,做一些针对性的处理等等。如有需要,可以选用。 单词释义 单词 释义 enum 列举型别 Season 季节 SPRING 春季 SUMMER 夏季 FALL 秋季 WINTER 冬季 name 名称 value 值 member 成员,members为复数形式 item 一件物品,items为复数形式 get 获取 month 月份 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-12 00:18:05 "},"chapter8/":{"url":"chapter8/","title":"八、异常处理机制","keywords":"","body":"八、异常处理机制 大家或许还记得我们之前写一些脚本的时候,如果执行时有报错,python的脚本就会直接停在报错的地方,给出报错信息,不再往下执行了。 在实际的程序中,这种中途突然罢工的操作可能会让应该执行的代码没能正常执行,可能压根无法达到我们需要的效果。作为一门成熟的编程语言,有异常处理机制是很重要的,它能将异常处理代码和正常业务代码分离,保证程序的健壮性,即时某些可能报错的地方报错,也不影响其他代码的正常继续执行。 python的异常处理机制,主要依赖try、except、else、finally、raise五个关键字,特别是前面两个,你会看到是类似于流程控制的形式来处理异常的。 本章的内容不算很难,有了前面流程控制的基础,相信你可以很快掌握异常处理机制,它在我们的实际开发中很重要,所以请大家务必要掌握哦。 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-12 10:42:14 "},"chapter8/8-1 python3小白课:最基本的异常处理.html":{"url":"chapter8/8-1 python3小白课:最基本的异常处理.html","title":"8-1 python3小白课:最基本的异常处理","keywords":"","body":"python3小白课:最基本的异常处理 为什么要进行异常处理 我们先来从理论的角度来谈谈学习和恰当使用异常处理的必要性。 在计算机程序编写的时候,没有人能保证自己编写的程序能永远不出错!就连我也不能! 即使保证了编写所有代码的语法全部正确,也没法避免突发情况,比如让用户输入内容的时候,你能保证用户不会输入你无法处理的内容?比如你能保证运行的电脑不会突然出现硬件故障?比如你能保证需要网络的程序,网络不会突然断掉?突发情况是我们无法一一枚举的,这时候脚本直接终止并不是一个好主意。 [!tip] 对于一个程序的健壮性而言,开发者仅仅做“对”的事是远远不够的,你还要考虑到很多东西,很多方面,有的时候,还需要堵住一些常见的漏洞,对整个过程要有全面的考虑。 当程序运行出现意外情况的时候,系统会自动生成一个Error对象来通知程序,如果我们没有做异常处理,那么程序就会像我们之前看到的那样直接罢工不干,如果我们编写了相关的异常处理代码,则会进行“错误处理”,以便让程序能够继续运行下去。 使用try...except结构捕获并处理异常 异常处理的通用结构语法如下(这是日常我用得最多的一种结构,一般来说,刚开始仅掌握这种结构也基本上够用了): try: # 业务执行代码,这里面可能会有让程序报错的代码,放到这里来 ... except Exception as e: # 如果在try块的代码中有报错的代码,则会执行except块的代码,否则不执行 ... 是不是很像流程控制的赶脚?对的,就是需要注意缩进的。 我们可以将可能出现问题的代码放到try块中,如果报错则会执行except块中的代码。Exception是一个通用的异常类,基本上各种异常都基于此类来派生,所以写它一般就可以了,至于其他更高级的应用我们后面课程会讲。as e是把捕获的异常赋值给一个自定义的变量e,当然你也可以写其他的名字,约定俗成一般用这个。这个e我们称之为被赋值后的异常对象,通过这个异常对象我们可以获取相关的异常信息。在except块中,一般可以print这个值e用来查看具体的异常是什么。关于异常对象,后面的课程中将会有更详细的讲解。 我们来看一个小例子: # coding:utf-8 try: # 除数不能为0,所以一定会报错 a = 1 / 0 except Exception as e: print(e) 是不是很简单呢? [!danger] 有的同学会说,那么我们把所有的业务代码都放到try块中不就不会有任何问题了吗?我们需要小心的是,在try语句块中的代码不要有太多,因为过多的代码语句放到try块中,出现异常的可能性就会大大增加,后续分析异常原因的难度也会大大增加。而且有的时候可能要针对不同的异常类提供不同的处理逻辑(关于不同的异常类,我们在后面的课程中会讲到),这样编程的难度就会增加。 所以我们的原则是,写多个try...except块,把感觉可能出现异常的程序段落分别写到多个try块里,分别捕获不同的异常并针对性处理。对于基本不大可能出现问题的程序段落,就像我们往常一样正常写就好了,可以不放到异常处理段落里。 单词释义 单词 释义 try 尝试 except 除...之外,这里为异常处理的关键字 Exception 例外 as 把...作为... division 除法 by 被... zero 零 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-12 16:19:15 "},"chapter8/8-2 python3小白课:多异常捕获.html":{"url":"chapter8/8-2 python3小白课:多异常捕获.html","title":"8-2 python3小白课:多异常捕获","keywords":"","body":"python3小白课:多异常捕获 在Exception类之下,还有许多其他的从它继承的异常类。我们可以针对不同的具体异常做针对性处理,写多个except块,也可以将多个子类异常合并到一起处理,我们来看一下语法: ## 多个异常类单独处理 try: # 业务语句 ... except Exception1: # as e这样的部分不是必须的 # 处理Exception1异常的语句 ... except Exception2: # 处理Exception2异常的语句 ... except Exception3: # 处理Exception3异常的语句 ... except: # Exception也不是必须的,这样也可以捕获所有类型的异常,通常写在最后一个 # 处理其他未知异常的语句 ... ## 也可以多个异常合成一个处理 try: # 业务语句 ... except (Exception1, Exception2, Exception3): # 处理框定这些异常的语句 ... except: # 处理其他未知异常的语句 ... 咱们来看一个小例子再巩固一下吧: # coding:utf-8 import sys while True: try: a = int(input(\"请输入a:\")) b = int(input(\"请输入b:\")) c = a / b print(\"商为:\", c) except ValueError: print(\"数值错误,仅能接收整数参数\") except ArithmeticError: print(\"算术错误\") except Exception: print(\"未知错误\") 比如输入的值不能支持变为整数时会报ValueError,当除数为0的时候,会报ArithmeticError等。 我们可以注意到,有的时候异常处理结构可以结合循环语句进行,在前面的例子中,我们在except块仅做了日志打印处理,在实际编程中这可能是还不够的。我们可以在异常捕获到之后,如果错误的数据能修复的尝试进行修复,将异常信息保存到一个日志文件中,也可以在这一步发送邮件、短信等通知合适的运维人员等等。完成异常正确处理之后,我们可以使用continue之类的语句控制进入下一次循环或者绕过这一条错误的条目。 单词释义 单词 释义 ValueError 值错误 ArithmeticError 算术错误 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-12 12:07:37 "},"chapter8/8-3 python3小白课:查看详细异常信息.html":{"url":"chapter8/8-3 python3小白课:查看详细异常信息.html","title":"8-3 python3小白课:查看详细异常信息","keywords":"","body":"python3小白课:查看详细异常信息 异常对象的属性 之前我们介绍过except Exception as e中的e这个被赋值的异常对象,它里面承载了一些异常的相关信息,我们是可以获取的。它有如下几个属性: args:该属性返回异常的错误编号和描述字符串。是errno和strerror属性的结合,返回的是元组。 errno:该属性返回异常的错误编号。 strerror:该属性返回错误的描述字符串 我们来看个简单的例子: # coding:utf-8 try: # 使用open方法打开一个当前目录的txt文本文件,如果文件不存在,会抛出异常 f = open(\"a.txt\") except Exception as e: print(e.args) print(\"-\" * 40) print(e.errno) print(\"-\" * 40) print(e.strerror) [!danger] 有的异常类没有一些属性比如errno,这时候强行获取这些属性可能会报错。 异常的传播轨迹 有一个traceback模块可以用来处理异常传播的轨迹,标明异常发生在哪个文件、哪一行、哪个函数处。 关于传播轨迹,如果你仔细观察,我们日常不进行异常处理的报错时看到的python解释器的Traceback就是传播轨迹。传播轨迹可能是层层传导的,有时候轨迹会很长,但不要惊慌,它们可能就是同一个错误引发的,每一个错误向上一层传导,直到传导到python解释器停止程序。我们需要学会阅读和理解传播轨迹,可以更好的帮助我们定位代码中存在的问题。 traceback模块常用的有如下两个方法: print_exc():将异常传播轨迹输出到控制台或者存到文件中。 format_exc():将异常传播轨迹转换成字符串。 我们可以来看一个实际的例子: # coding:utf-8 import traceback try: # 使用open方法打开一个当前目录的txt文本文件,如果文件不存在,会抛出异常 f = open(\"a.txt\") except Exception as e: # 将异常传播轨迹信息输出到控制台 traceback.print_exc() print(\"-\" * 40) # 将异常传播轨迹信息保存到log.txt文件中,打开文件的模式为a(追加内容模式) # 这一步不会有任何的内容输出到控制台 traceback.print_exc(file=open(\"log.txt\", 'a')) print(\"-\" * 40) # 将异常传播轨迹信息转换成文本,但如果要在控制台输出需要加print print(traceback.format_exc()) 这里详细演示了几种用法来展示异常传播轨迹信息,大家可以根据自己的需要,选择使用。 单词释义 单词 释义 args arguments参数的简写形式 errno error no错误编号的简写形式 strerror string error错误字符串的简写形式 open 打开,一个内置的打开文件的命令 traceback 回溯,追溯 print_exc print exception打印异常信息的简写 format_exc format exception格式化异常信息的简写 file 文件 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-12 17:08:37 "},"chapter8/8-4 python3小白课:异常机制中的else块.html":{"url":"chapter8/8-4 python3小白课:异常机制中的else块.html","title":"8-4 python3小白课:异常机制中的else块","keywords":"","body":"python3小白课:异常机制中的else块 在python的异常处理中还能加入else块,简单来说,当try块的代码没有出现异常的时候,会执行else块的代码。 我们直接来看一个很简单的例子: # coding:utf-8 try: print(\"我没有异常\") except: print(\"发生异常情况\") else: print(\"我是else块,因为try块没有异常执行我\") 可以看到,else块中的代码被正常执行了。 有的同学可能会有疑问,既然这样,咱们把else块中的代码放到try块的末尾去执行不就好了吗? 我们来根据这样的想法,修改一下例子如下: # coding:utf-8 s = input(\"请输入除数:\") def else_test(): result = 100 / int(s) print(\"100除以%s的结果为:%s\" % (s, result)) def wrong(): try: print(\"try块代码可能有异常\") else_test() except: print(\"程序出现异常\") def right(): try: print(\"try块代码无异常\") except: print(\"程序出现异常\") else: else_test() wrong() right() 如果我们直接输入一个会异常的除数:0,执行一下会发现,将代码写在try块中,except块会捕获异常,并处理异常,但当会异常的代码写在else块中时,except块不会捕获异常,而是会直接终止程序。 根据这样的试验结论,如果我们系统某段代码的异常能被except块捕获并处理,则将代码写在try块中即可;如果希望某段代码的异常能向外传播(不被except捕获),则可以将代码放在else块中。 可能有的同学还有这样的疑问,当else_test()这部分可能引发异常的代码放在else块中时,会向外传播异常,甚至终止程序那么我直接把这块代码写在异常处理块的外部,不是效果一样的吗?比如我这样写?(仅写修改的部分) try: print(\"try块代码无异常\") except: print(\"程序出现异常\") else_test() 没错!这样写似乎的确是一样的,那么else块的作用还体现在哪些方面呢? [!tip] 我遍寻了网上很多资料,其实各种网站、博客都没有说清楚这一点,那就是,else块的作用,除了当try块的代码没有出现异常的时候,会执行else块的代码以外,还有一个延伸的话,那就是当try块代码有异常的时候,就不会执行else块的代码了! 而如果你将else块的代码写在异常处理块的外部,则无法实现这样的效果。 上述代码可以改成这样: # coding:utf-8 s = input(\"请输入除数:\") def else_test(): result = 100 / int(s) print(\"100除以%s的结果为:%s\" % (s, result)) def wrong(): try: print(\"try块代码可能有异常\") else_test() except: print(\"程序出现异常\") else: print(\"不会执行我这句代码,因为try块有异常\") def right(): try: print(\"try块代码无异常\") except: print(\"程序出现异常\") else: else_test() wrong() right() 可以看到,当输入除数0的时候,print(\"不会执行我这句代码,因为try块有异常\")这句代码永远不会被执行。 实际运用的时候你可以根据需要来使用else块,从我个人的角度,else块用的确实不多,所以咱们不做为重点。 单词释义 单词 释义 wrong 错误 right 正确 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-12 18:20:53 "},"chapter8/8-5 python3小白课:finally块回收资源.html":{"url":"chapter8/8-5 python3小白课:finally块回收资源.html","title":"8-5 python3小白课:finally块回收资源","keywords":"","body":"python3小白课:finally块回收资源 finally块的了解掌握 异常处理机制中,我们还可以加入finally块,通常用来做回收资源等的操作。比较典型的是打开了某个文件,使用完毕后需要关闭这样的处理,交给finally块来处理最合适不过。因为finally块是最后执行的,无论try块有没有异常,finally块的代码都会得以执行。即使在try块等代码中含有return等语句,也会先执行finally块的代码,才会执行return结束方法。 我们先来看一下结合了前面所学区块后的异常处理机制语法结构: try: # 业务实现代码 ... except: # 如出现异常的处理代码 ... else: # try块没有异常会执行的代码 finally: # 一般用作资源回收块 ... 可以看到,finally块是放在结构的最后方,需要注意顺序这一点。except块和finally块至少出现其中之一,也可以同时出现(所以except块也是可以没有的哦,但最好不要没有)。我们来看个小例子: # coding:utf-8 try: a = 1 / 0 finally: print(\"执行完毕\") 这样执行,我们会发现,finally块的代码是可以正常执行的,即时try块有报错并且没有处理。 一般来讲,我们会这样写关闭打开的文件资源: # coding:utf-8 def test(): # 先定义一个局部变量f,否则如果open报错,f变量将会找不到,if f语句会报错,找不到变量 f = None try: f = open(\"a.txt\") except Exception as e: print(e) return # 这个return是加来测试的,平时可以不加,有return的情况下,finally块的代码依然被执行 finally: print(\"正在执行finally块的代码\") # if f指的是当f的布尔值不为False,就会执行后面的代码,如果文件没打开成功,则f布尔值为False if f: f.close() test() [!danger] 在finally块中,尽量不要使用return或者raise等导致方法中止的语句(raise我们将在后面的课程中讲到),否则可能会出现编程逻辑混乱等一些奇怪的情况。 我们来看一个小例子说明这件事: # coding:utf-8 def test(): try: return True finally: return False a = test() print(a) [!question] 猜猜看,打印出来的会是True还是False?你可以在你电脑上试试看! 结果,是False! 为什么呢?我们可以来看一下程序运行的流程,首先调用test函数,执行try块的代码,碰到了return True这样的return语句,这时候程序会暂时不会执行它,先执行finally块中的代码,结果在里面遇到了return False语句,所以直接返回结束了该方法,这样结果就是False了。 异常处理可嵌套 我们学习了这么多的异常处理结构,每次遇到try块都是独立出现的吗?非也,有的时候根据业务需要我们还可以在try块、except块的内部再嵌套try...except语句,这就叫做异常处理的嵌套,这是支持的,比如在except处理的过程中,里面的代码又引发了新的异常?这时候就可以用异常处理嵌套来实现。 [!danger] 异常处理嵌套对于深度没有要求,但一般不要超过两层,太深其实也没有必要,太深容易降低程序代码的可读性。 单词释义 单词 释义 finally 最后 close 关闭 raise 提升,提起,在python中用来引发异常 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-12 20:10:10 "},"chapter8/8-6 python3小白课:自己引发异常.html":{"url":"chapter8/8-6 python3小白课:自己引发异常.html","title":"8-6 python3小白课:自己引发异常","keywords":"","body":"python3小白课:自己引发异常 raise引发异常 当程序出现系统预先内置定义的异常类的时候,会自动引发异常。但有些时候,我们根据业务的需要,某些计算得到的业务数据不符合规范等场景,在我们看来也属于异常结果了,这些异常我们想要进行特别处理,这时候就需要我们通过代码来自己引发异常。 在python中,可以使用raise语句来引发异常。 raise语句有三种常见的用法: 只用raise关键字:会引发当前上下文中捕获的异常,默认会引发RuntimeError异常。 raise 异常类名称:raise后带一个异常类,引发指定异常类的默认实例。 raise 异常类名称(描述信息):引发指定的异常对象。 这几种方法本质上都是引发一个异常实例,而一个raise语句只能引发一个异常实例。 来先看个例子吧: # coding:utf-8 a = 1 if a == 1: raise 运行后我们可以看到,raise语句可以脱离try结构而使用,但一般没啥实际意义,会自动触发默认的RuntimeError。 我们一般会这么用: # coding:utf-8 try: a = 1 / 0 except Exception as e: print(e) raise 可以看到,try块有异常触发了except块的代码,先打印了异常对象e的内容,然后使用raise再次引发了上下文的这个ZeroDivisionError异常。 我们还可以这样写: # coding:utf-8 try: raise ValueError except ValueError: print(\"触发了ValueError异常\") except: print(\"触发了其他异常\") 还可以指定异常信息: # coding:utf-8 raise ValueError(\"值异常,我自己写的信息\") 自定义异常类 前面部分的学习是让我们掌握了触发异常类的方法,在使用raise关键字的时候,不单单只能引发系统已经定义好的异常类,你还可以自定义你自己名字的异常类,这样可以更明确的展现异常,最大限度地提供异常的有用信息,raise语句也可以触发自定义的异常类。 自定义的异常类都应该继承自Exception基类或者它的子类,而且定义也很简单,无需书写过多代码,只需要指定自定义异常类的父类即可。举个例子: # coding:utf-8 # 名字只是为了让程序更加有可读性,你可以自定义异常类类名,一般加个Exception结尾啥的好认 class XiaobaiException(Exception): pass raise XiaobaiException(\"小白报错啦!\") 单词释义 单词 释义 raise 提升,提起,在python中用来引发异常 RuntimeError 运行时异常 ZeroDivisionError 零除异常,除数为0的时候抛出 ValueError 值异常 Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-12 20:47:35 "},"Summary.html":{"url":"Summary.html","title":"课程总结","keywords":"","body":"课程总结 经过了十几节课的洗礼,恭喜大家走到这一步,如今,正式python入门啦! 这套python3小白课,我使用了最通俗易懂的语言和最简洁的例子,将大家python入门需要掌握的一些知识悉心传授给了大家,希望大家在日后的python学习中,都能以本套教程为基础,徜徉于编程的海洋,不断拓展自己的能力,因此而终身受益。 本套课程也支持大家在未来遗忘某块知识的时候反复回看,用于巩固基础,这都是很好的。 将所学学以致用,那才是最好的,我真心希望大家学习完成后能够自我进行代码练习,巩固所学到的知识,一段时间后,能够脱离教程而编写出自己的东西,那,才是真正的毕业,也是我所希望的。我不希望大家脱离教程之后就丢失了应有的编程思维,这是应该逐步培养的,我希望大家可以自觉做到不看教程这一课的内容能够自己复述出来或者代码演示能够写出来了,那,才是真正的毕业了。 祝愿大家学有所成,前程似锦,咱们后会有期! Copyright © 雪山凌狐教程 all right reserved,powered by Gitbook该文件修订时间: 2020-07-12 22:02:42 "}} |