粉丝1.9万获赞5.3万

蛇,你还学点新技能吗?当然要学和蛇有关的了。拍档了解一下拍档编程语言名字的本意啊,就是大蟒蛇,本视频会带你只用三个半小时,从零基础啊,速通拍档基础,直接重点讲解经验,绝不废话。 而且因为视频有大量插图、动画和生物画粒子,相信我啊,学习过程绝不痛苦,让你能够轻松理解抽象烧脑的编程概念。我们开始吧! 在写下第一行拍档代码之前,你还有两件事情需要做。第一件事情是安装拍档解释器,机器其实是没办法直接读懂我们写的拍档代码的,而是需要一个解释器作为中间的翻译,把代码转换成字解码后再执行。 拍档的运行过程就是翻译一行,执行一行。我们一般说安装拍档,本质上指的就是安装拍档解释器。 第二件事情是安装一个代码编辑器,这好比我们写文档大多数用 word, 像写代码也需要一个软件,现在已经有非常多的代码编辑器,关于哪个编辑器最好用这个话题都可能挑起程序员之间的战争。 我比较推荐的是拍唱,他是 jet prince 公司,简称 j b 公司,专门为拍档设计的编辑器。 而且拍唱不只可以用来写代码,它的本质叫做 i d e 集成开发环境,除了拥有代码补全、自动格式化、拼写检查等许多编辑器智能功能之外,还包含了调试器、版本控制工具等,非常强大。 但是作为新手呢,不需要一次学会所有的,随着经验增加,你上手的功能会越来越多。后面两个视频会带着你一起在 windows 系统或 这麦克 os 系统上安装这俩东西,我们稍后见。这个视频里我会和你一起在 windows 上安装拍档和拍 char, 如果你的电脑不是 windows 系统的话,可以直接跳过这个视频, 我呢会带你从官方渠道下载拍档解释器和拍叉。首先下载拍档,搜索拍档官网,找到有官方标签的网页点进去,或者呢也可以直接就在浏览器的地址栏输入 w w w 点 python, 点 org, 进到这个页面之后啊点击 downloads, 也就是下载,可以看到这个网站应该是能够自动识别出你的系统,比如这里会显示 four windows, 这样能保障下载的版本啊,是能正确适配到你电脑系统的。 接下来直接点击这个大黄按钮,就会开始下载最新版本的拍档。如果你的版本号啊和我这里显示的不一样,不是三点十三版本也没什么问题,只要是三开头的就不会有什么大的差别。 下载完成之后打开它开始安装,这里一定注意注意,再注意 add python to path, 也就是把 python 路径添加到环境变量中,要勾选上,让电脑知道你的 python 安装到了哪里, 然后点击这个 install now, 就会开始安装啦。稍等片刻,等它安装完毕。如果这里啊出现了这个路径长度提示,点击它,把它点没掉,然后点击 close, 关闭这个安装窗口。为了测试是否安装成, 在菜单栏搜索 cmd, 进入命令提示服,进入拍档,注意是全消息啊,然后点击回车,如果显示出拍档,后面跟着你刚才安装的版本以及这些乱七八糟的一串话,说明你电脑上现在已经有拍档了。 接下来要做的是安装拍唱,搜索拍唱官网,如果点进去是这个网址, w w w there are jet prince there come 斜杠拍 charm 说明没错,然后还是找 downloads, 点击这个绿按钮,会跳转到新的页面。 拍叉米有两个版本,专业版和社区版。专业版是收费的,社区版是免费的。我们眼前的这个啊,是专业版,但对纯拍档开发者来说,社区版已经够用了,所以我们往下划拉划拉,这个 multi edition 就是免费的社区版。然后我们点击黑色的 download 按钮,下载免费版本。 下载完成后打开它,跟着安装指引,点击下一步,然后选择要安装到的位置。想要有桌面图标快捷方式的话,把这个勾选上。想让所有拍照文件都用拍唱打开的话呢?嗯,最后这个也可以勾选上, 再点击下一步,等待安装完成。因为拍唱这个软件蛮大的,需要花一些时间安装。 点击完成,关闭安装窗口。接下来啊,打开拍唱,他会弹出一个窗口,让我们选择语言和地区。因为我的操作系统是中文的,所以他默认也是中文了。但如果你的不是中文也没有关系,我们后续也会教你如何把它设置成中文的。 我们点击下一个,然后我们需要先同意用户协议,像我平时就是不太看用户协议的。如果你有安装其他的代码编辑器,他会问你要不要导入其中的配置,我不需要,就先挑过。 现在你已经在 windows 上完成了拍 charm 的初始化,可以开始用它创建项目和携带码了,我们后面视频见。 这个视频里我会和你一起在麦克电脑上安装拍档和拍唱。如果你的电脑不是麦高压系统,可以直接跳过这个视频, 我呢会带你从官方渠道下载拍档解释器和拍叉,搜索拍档官网,找到有官方标签的网页,点进去,或者也可以在浏览器的地址栏直接输入这个地址 w w w 点拍档,点 org, 进到这个页面之后, 点击 downloads, 也就是下载,可以看到我这个网站,应该能自动识别出你的系统,比如这里会显示 four remigos, 保障下载的版本啊,是能正确适配到你的电脑系统的。 接下来直接点击这个大黄按钮,就会开始下载最新版本的拍档。如果你的版本号和我这里显示的版本号不一样,不是三点十三版本也没什么问题,只要确保是三开头的,就不会有什么大差别。 下载完成后啊,打开它开始安装,这里可以一直点击下一步,然后输入你的 mac 用户名和密码。安装过程是需要管理员权限的, 然后就会开始安装了,稍等片刻,等他安装完毕,然后关闭这个安装窗口。为了测试是否安装成功啊,我们需要打开电脑的终端,方法一, 一是点击顶部菜单栏这个放大镜图标,输入终端打开。方法二是点击访达,然后在顶部选择前往使用工具,找到终端,打开, 然后我们输入拍档。三,注意啊,是全消息,然后回车。如果显示出拍档,后面跟着你刚才安装的版本以及这些乱七八糟的遗传话,说明你现在电脑上啊已经有拍档了,恭喜恭喜, 接下来我们要做的是安装 pychar, 搜索 pycharm 官网,如果点进去啊,是这个网址 w w w 点 jack prince 点 com 斜杠拍唱说明没错,然后还是找 downloads, 点击这个绿色按钮,会跳转到新的页面。拍唱有两个版本,专业版和社区版。专业版是 收费的,社区版是免费的。我们眼前的这个是专业版,但对纯拍档开发来说,社区版已经够用了,所以我们往下划拉划拉,这个 community edition 就是免费的社区版。 另外这里注意了,你最好检查下按钮右边括号里这个芯片是否匹配你的电脑。比如如果你的 mac 是 m 系列芯片, 你就要点下拉按钮,把下载的版本切换为匹配 apple cdcon 芯片的。但因为我的电脑啊就是英特尔芯片是匹配的,所以我直接点击黑色的 download 按钮,下载免费版本。 下载完成后,打开它,把 pycharm 拖进应用程序文件夹,它现在应该就在你的应用程序文件夹里了。你也可以直接搜索 pycharm, 点击打开它呢,会弹出一个窗 口,让我们选择语言和地区。我这里默认已经是中文了,但如果你的拍唱显示的并不是中文也没有关系,因为我们下一个视频就会教你如何设置成中文,然后我们点击下一个。接下来呢,我们需要先同意用户协议,像我平时就是不太看用户协议的, 然后选择是否分享匿名数据啊,无所谓,都可以。那接下来啊,如果你的电脑也像这样弹出提示询问文件的访问权限的话呢,点击好就可以,然后如果你有安装其他代码编辑器的话,他会问你要不要导入其中的配置,我不需要就先挑过了。 现在你已经在 macos 上完成了 picharm 的初始化,可以开始用它创建项目和谐代码了。我们后面视频见,跟着前面的视频,你应该已经完成了 picharm 的安装, 可以创建一个自己的项目了。首先打开拍唱,因为我们一开始选择了语言和地区,所以这时候你的拍唱可能已经是中文的界面了。但是如果说你的界面还是英文的话,下面先教你怎么把它设置成中文。 在欢迎页面点击左下角这个位置的设置图标,点击 preferences 偏号设置的意思,如果你是 windows 系统,这个图标对你的名字是 settings, 然后在左侧找到这个 plugins, 这是插件的意思,如果找不到的话,可以在左上角这里输入 plugins 搜索一下,然后在插件页面的搜索框里输入 chinese。 如果能找到这个简体中文语言包的话,我们就点击 install 安装。但如果像我一样啊在 marketplace 里搜索不出来简体中文语言包,说明他可 可能已经默认被安装了,那就点击旁边这个 install 的看看。如果它是灰色的禁用状态,我们就把它勾选上,然后点击右下角的 apply ok, 接下来我们再次点击左下角设置里的 preferences 或者是 windows 上的 settings。 这次我们要搜索的是 language, 然后往上滑了,找到 language and region 这栏,点击它,在这里选择中文,点击 ok, 然后点击 restart 重启一下得啦,现在页面上的语言就变成中文的啦。 现在我们要创建一个项目,让我们可以集中管理代码文件,在欢迎页面找到新建项目,点击它这里的第一行,表示你的项目文件夹所在的位置,你可以换成其他 好找的位置,比如说在桌面上,但记得要先创建一个文件夹,然后选择那个文件夹,不然拍叉会把你整个桌面当成项目文件夹。下面这个解释器类型,我们可以选择默认的项目。 v inv 拍唱会,自动检测你电脑里的拍档版本,如果你还安装了其他版本,可以下拉,找到你想要的那个版本, ok, 然后点击创建 每个项目文件夹,里面啊放的应该都是和这个项目相关联的文件,比如一个网站项目啊,里面就会是像前后端代码、图片素材之类的东西,你不要把什么身份证照片啊,毕业论文啊都随手往里放。 这个拍叉 m 自动帮你创建了一个 v n v 文件夹,表示这个项目独立的拍上虚拟环境。目的呢,是让不同项目可以用不同的解释器版本,以及 安装的第三方库等等。第三方库这个东西啊,我们后面还会接触到,当前只需要记住一点,这个文件夹不要动它,不要删它,也不要往里塞东西。 那走到这一步,你已经打败全国百分之九十九的人了。因为啊,在自己电脑上设置本地开发环境总是不容易的。之后呢,如果你要创建其他拍档项目文件夹,就按照相同的步骤重复即可。 然后你可能好奇啊,这里要怎么开始写代码,根本没有可以编辑的地方。如果你要写代码的话,就点击这个文件夹,右键新建,选择拍同文件,然后取个名字, 比如我这里叫 hello, 然后末尾加上点 p y, 然后回车。现在你就有了一个可以编辑代码的地方,我们下个视频见。 小代码与其说是和计算机交流,更准确的说法是给计算机下指令,只要有权限,而且指令能让计算机听懂,计算机就会按照你说的照做。 比如你叫你朋友喊一声爸爸,他不愿意可能还给你一巴掌,但让程序执行叫爸爸就非常可亲。用拍档代码,只需要这样一行,电脑就会在屏幕前显示 dad。 我们来拆解一下 print 这个词在英文里面的意思是打印,可以理解为把指定文字在屏幕上展现出来, 这个括号是给你往里面放要打印的东西的,如果你把东西放到了括号外面,那就不归这个 print 管,他就不会给你打印出来,而且还可能会报错。还有要瞪大小眼睛留意的是,这个括号是英文的括号, 不是中文括号。有些时候中英文标点符号会长得比较像,比如括号、逗号、分号、方括号这些的,但仔细看还是能看出差别,像中文符号会占的比较宽。编程语言指认英文标点,所以记得切换输入法的语言。 接下来这一堆引号也很重要,用单引号或者双引号都可以,但也必须得是英文标点包裹住要打印的文字。就像我们书面写作的时候,也需要引号来区分原文和其他部分。 比如这个例子,如果备注的是刻上引号,天道酬勤引号,那就不会有这种误会了。写程序也一样,要避免任何误会。如果不加引号,计算机就不会把里面的内容当成是文字,而是当做我们后面才会学到的变量。 括号里面包着的是我们想要打印的内容。 dead 作为文本内容,本身就可以出现中文以及中文标点了,但引号以及引号外面的还是必须得保持英文标点。这个引号以及里面的文字内容一整个叫做字符串,也就是一串文字的意思, 即使里面放的全部都是数字,有了引号,这整个都会被视为是字符串六六六,而不是数字六百六十六。现在是实践时间,带你在自己的电脑上打印字符串, 打开拍唱,你之前创建好的第一个空项目应该会出现在这个最近的项目里面,如果没有的话,你也可以在这里点击打开,然后找到他的文件加位置,或者干脆再创一个新的, 然后我这里就直接双击打开之前创建好的项目。点击侧边栏项目,可以调出所有的文件夹, 要在这个项目文件夹下添加一个 python 文件,前一个视频示范过,就是先选择这个文件夹。 注意不要创到这个 vnv 文件夹下面了,因为他是这个项目的虚拟环境文件和咱们的代码是应该分开的,所以点击最上面这个文件夹,点击右键新建拍档文件,输入一个名字, 我这里叫 e print demo 吧,后面跟上点 p y 表示拍档代码文件后缀,然后建议大家文件名尽量不要有空格,比如说像这样或者是 奇怪的符号,比如说放个 emoji 在里面,总之英文数字下划线这种最好,可以避免有时候无法根据文件名找到文件之类的问题。然后点击回车创建文件, 如果你是第一次创建文件,这里可能会弹出一个窗口询问是否添加到 gate。 当前入门阶段,咱们先不用管他,如果出现你就选择不再询问,然后点击取消我这里因为之前选择了不再询问,所以他第二次就没有再弹出来给我。 然后在这个文件里写下咱们的打印语句,先是 print pr, amt, 全部都是小写,这里其实是拍唱给的一些提示,比如说我直接写 pr, 他其实已经在给我提示一些里面包含 pr 的关键词了,然后是括号,一对引号,然后写下咱们的想要打印的这样一个内容。现在代码写完可以运行了,你可以在这里直接右键点击运行, 可以看到下方这里的运行窗口就会展示运行的结果,成功的展示出了咱们想要打印的内容。 dad。 然后第一行和最后一行可以忽略,上面那行是拍 charm, 在你点击运行后帮你自动触发的运行指令。 下面这行如果显示退出代码为零,表示运行没有出现错误,如果有错误的话,这个退出代码会是一个非零的数字。这两行其实都是拍唱,每次运行的时候 都会自动展现的,所以可以忽略。你主要需要聚焦的是第一行和最后一行之间的内容,这个双引号里边的内容可以替换成任意你想要的,比如中文的叫妈妈也行, 咱们还是右键选择运行,这个妈就打印出来了。如果你的代码有问题,比如说括号用成了中文, 像这样 title 会自动用红色提醒你这里有问题,你在运行的时候也能看到红色的错误提示信息,比如说像这样 以及这里的退出代码也变成了不为零的数字。如果你看不出来到底哪里有问题,可以把这个红色的错误信息复制到百度 上面,你自己的文件名和代码就不用复制了,毕竟大家代码不一定一样,但是错误可能是相似的,所以你可以把这一行复制,然后粘贴在搜索引擎里。 可以看到很多人都遇到过相似的问题,所以把错误信息复制到搜索引擎进行搜索,很可能能够帮助你解决问题。接下来教你打一些更复杂的东西,我们下个视频见。 打印字符串还有进阶玩法,这里介绍一些最常见的。第一,字符串连接,字符串上个视频说过,就是用引号包裹住的一串内容,你可以把几个字符串用加号连 接成一个更长的,再打印出来,打印结果就是每个字符串按顺序拼接而成的一个更长的字符串。这里因为不知道前面有一个空格,所以打印出来中间才会有空格,否则两个词就会驮到一起。 第二,单双引号转移。上个视频里说过,字符串用单引号或双引号裹着都可以,效果在绝大多数情况下都是一样的。但如果我内容本身里面就有引号,就需要留意内容里面的引号和外面包裹字符串的引号具体是单还是双。 像这句代码,运气是会出错的。第一个引号没问题,第二个引号拍档会理解为和前面那个引号配对,表明字符串结束了,他就觉得 he said 就是完整的字符串了。 一直往下,他又懵逼了,这个 good 改单号引号,引号又是什么玩意?于是报错说你代码有问题。但如果你把外面的换成单引号,他就知道没有问题。因为和最开头单引号配对的,在结尾说明里面包着的这对双引号都是字符串的内容, 把里面换成单引号也是一个道理,外双内单也不会报错,但这样实际打印出来的就会是单引号。 那如果一句话里面好死不死,有单引号又有双引号怎么办嘞?其实也有办法,你可以在字符串里面的引号前放一个反斜杠, 来表明后面的引号就是单纯的引号,符号是内容的一部分,并不表示字符串的结束。这个看着有点眼花,但他打印出来会是这样一句, he said let's go, 可以看到里面斜杠后面直接跟着的引号都被原封不动的打印出来了。这个反斜杠叫做转移符,只要字符串里面有反斜杠,拍档就会知道要把这个反斜杠以及后面跟着的符号一起读,产生特殊的意思。 第三,换行。拍档里面一句代码不能随便换行,像这样子就会报错,因为拍档读一行,执行一行,读到第一行结尾,看你没有结束引号和括号,以为你忘了,于是直接报错,根本不往下读第二行了, 你说我就是想要这个 hi, 打印到下一行怎么办?其实也有办法,斜杠后面跟着 n 表示换行,这是反斜杠转移符的另一个用法。打印的结果就是这个 hi 在第二行第四、 三言号跨行字符串,如果打一首诗,按照前面的方法换行,非常头疼,要么每句后面都加上反斜杠 n, 产生换行效果,要么就是写很多 print 语句,因为每个 print 都默认另起一行。 这里隆重介绍三引号,三个连在一起的单引号或双引号,用它包裹住文字拍档,就会把新的一行当成内容的换行,而不是代码语句的结束,这对打印跨行多的内容非常方便。然后是我们的实践时间, 我还是在之前的项目里新建一个空白的 python 文件 粒子。一是支付串连接, 还是咱们熟悉的 print 括号,然后里面可以放多个字符串,中间用加号连接,比如 print。 你好,接下来是加号,再加一个空格,这是 去代码。这个加号两边的空格其实是可有可无的,但是加上空格以后会显得更加美观,但千万别在每行的开头随便加空格,像我这里加上以后,拍照已经在提示我有错误了, 开头空格的重要性学到后面你就会知道,然后再加一句,哈哈, ok, 然后咱们运行一下,可以看到成功的打印出了完整的句, 中间有这个空格,是因为我这里也有加空格。第二个例子,单双以后转移还是 twink, 比如先试一下不加反斜杠转移字符,咱们打印一个 let's go。 可以看到这里拍叉米已经明显的开始在提示错误了,因为他把这个理解成了完整的磁符串,他就不知道后面这一部分是什么了。所以咱们在这里给他加上反斜杠, 可以看到现在就没有错误提示了,并且这个反斜杠和后面的单引号用了同一个颜色标记出来,说明他们俩是一伙的。你这里需要注意的是,这个是反斜杠,他不是正斜杠, 反斜杠是键盘 enter 键的上面的一个,如果你搞个正斜杠,他就是没有用的。 回到反斜杠,咱们运行试一下。好的,可以看到这个 let's go 也成功的打印出来了。例子三是换行符,咱们试一下 print 出两行,我是第一行,然后还是反斜杠加一个,嗯,我是第二行, 咱们打印出来试一试。这里可以看到换行成功,第二行已经在自己的单独一行了,然后你可以单独拼的出一行换行符,这样子的话就会出现一个空行。 比如像这样例子四三引号跨行输入,咱们先试一下还是 print, 然后是三个单引号或者三个双引号拍唱,它比较智能,打三个引号后就会自动补上后面的撒。这里我来复制一首诗, 直接粘贴到这之间,然后运行,可以看到他的换行已经被原封不动的打印出来了。 打印了这么多乱七八糟的,你可能疑惑这有啥实际意义呢?学了变量你就知道打印的其中一个重要用处了。我们下个视频见 有这么一个场景,我们有个想频繁使用的字符串,比如你对象的手机号,这个字符串很长,因为手机号一般十一位码,反复打很麻烦,你可能还根本记 不住,这个时候就想有没有可能把它存起来。现实里我们有个叫通讯录的东西,可以通过人名找到手机号,这个人名相当于一个标签,通过这个标签我们可以获得他对应的值。 程序里的变量也是一样的,意义是用来储存或者只带值的。我们要先给变量取个名字,变量名中间不能有空格,也不能是数字打头。另外也千万别用引号包住他,因为有了引号就成了字符串, 然后是等号,后面跟上变量对应的值,这个叫做负值操作,也就是给变量一个值的操作。负值后,我们就可以通过变量名获取那个值。反复使用啊,必须要每次都重新打一遍。另外拍档是 从上到下执行的,你必须要在前面先对变量进行复直,然后才能用那个变量,否则就会报错。就好比你还没把对象电话存进通讯录里,就像通讯录要电话号码,那必然没有结果,那程序也不是个算命的,没法帮你掐指算。 那假设你对象换了个号码,或是你换了个对象,那 my love 这个手机号也得跟着变。很简单,还是用复制操作,给他复成另外一个值就好了。变量之所以叫变量,就是因为他可以变, 现在打印出来的就是新的手机号,你也可以用变量给变量复制,比如 my love 这个变量已经被复制了你前任的手机,你现在又用信任的手机号覆盖掉那个值,但又不想失去之前的值,那咋办? 你可以用另外一个变量,比如叫 my x 先储存你前任的手机号,再对 my love 负心的值。 第二行就是利用 my love 变量的值直接给 my x 变量复值。复值操作里,等号左边的会被识为变量名,等号右边的会先被求职得到幺三七那个手机号,然后把这个值也分配给 my x 变量, 最后 my love 被重新复制为现任的手机号,这样你就同时保留了前任和现任的手机号。 前面的视频我提过一嘴, print 在有变量的情况下很有用,因为在程序逻辑复杂的时候,可以用 print 打印出变量当前的值,帮助了解运行情况。下面是实践时间, 这里我就不用手机号做例子了,主要是太长了,懒得打。那假如咱们有这么一个打招呼的语句,叫您好吃了吗?比如说给张三打招呼,咱们就 print 您好吃了吗? 加上名字字符串。张三,然后再给李四打招呼,我们还是打印您好吃了吗?加上名字字符串李四。 但如果你要给很多人打招呼,这个您好吃了吗?字符串不知道要被重复打印多少次,所以我们可以给一个变量复值,比如说让 great, 也就是打招呼的意思, 让他等于这个您好吃了吗?字符串。那么下面的所有的打招呼都可以被直接简化成 great, 加上名字字符串。比如说像这样子, 那如果你后面要继续给其他人打招呼,比如王五,那也非常容易,直接跪着加上名字字符串就好了。咱们打印出来看一看, 可以看到打印出来的结果是复合预期的。那如果现在我们要把这个 great 换成呃一个英文打招呼,比如说 you what's up, 也可以直接在代码上进行替换。 可以看到使用变量的好处就是你只要把变量的值更新以后,下面每一处用到变量的地方也都会自动的变成新的值。 比如咱们这里运行一下,可以看到所有的都变成了英文的打招呼,但你说这样子是不是丢失了之前的中文打招呼? 是的,变量一旦发生替换,就找不到之前的纸了。那咱们也可以这样做,咱们可以把之前的中文打招呼方式给储存起来,然后再进行替换。所以咱们可以这样,先定一个 great, 让他等于之前的 great, 然后再搞一个 great english, 让他等于我们新的职, 最后再把 great 更新成这个 great english, 咱们打印出来看看。现在 所有的打招呼应该还是英文的,但同时咱们还保留了中文打招呼的方式,比如如果我想切换成中文打招呼,咱们只需要用这个 great chinese 就好了。 这个视频先讲这么多,那至于如何给变量命名呢?比如说这个 great, chinese, great english 这些有没有命名规则呢?之前提了一下,里面不能有空格,不能是数字开头。至于其他的规则或者说约定俗称,我们后面相聊,下个视频见。 在我们对变量及新闻复制操作后,后续也都是要靠变量名来获取或更新值,所以名字很重要。给变量取名有硬性规则,只能由文字、数字、下滑线 组成,不能有除了下划线之外的符号,不能有空格以及不能数字开头。如果你违反了硬性规则,排挡会直接报错, 但不报错也不代表都是好名字。变量应该尽量取的易于理解和记忆。如果随便取什么 aaeabc 这种名字,可能过几天你就想不起来他们是干什么用的了。那哪些名字算好,哪些名字算不好呢?这里给出的首要建议是, 第一是拼音阅读速度慢,写个用户名的拼音要整个读一遍才知道是什么意思,还不如英文 used name 更加直观和好理解。第二是拼音不带声调,容易产生误解。比如你想定一个变量叫高级记录高中年级属性,结果别人一看不能, 你创个叫搞基的变量是要干啥?第三是如果和我一样平时不太分平翘舌前后鼻音,就更不要勉强自己用拼音了好不。 开放在三点零版本之后开始支持中文变量名,不过现在主流仍然是用英文单词做变量名,原因是,第一,即使语言本身支持中文变量名,如果控制台或日志等编码不兼容,还是会展示出乱码。 第二,由于代码的关键字和符号仍然是英文的输入法,切来切去还是有点麻烦。第三,搜索一下英文翻译这件事情也并不难,所以大家也大多保持着英文命名的习惯。 拍档的英文变量命名约定俗称是使用下划线命名法,字母全部小写,不同单词用下划线 分隔开,比如用户年龄 user age、 用户性别、 user gender 这些原本会用空格的地方都用下划线去连接。命名也有其他风格,比如驼峰命名法,用大写字母来区分不同单词,但拍档变量命名一般还是用下划线命名法。 另外两个需要注意的地方是,第一变量名是大小写敏感的,也就是 user age 和 user age 会被看作两个不同的变量。 第二是变量名不要占用拍档关键字,比如 print。 如果你对 print 进行复制操作,比如说复制成字符串后,你就不能再用 print 来打印了,因为他在当前这个程序里不再是具备打印功能的函数关键字当前有三十几个,这些后面都会成为你很眼熟的 词,所以不需要现在死记拍唱,也会对拍段关键字进行颜色高亮展示。如果你发现打印出来的变量名是彩色的,说明那是关键字,最好换成其他的。先说这么多,下个视频见。 不知道你有没有这样的经历,用计算器或手机计算器上计算一个比较复杂的算式,输入到中途感觉自己可能手滑,按错了一个键,于是进退两难,不知道是继续还是全部清空重数。 还有一种按着按着忘了算到哪里的情况也很让人崩溃。如果你会用拍档写数学运算,可以完全避免以上情况,用代码秒杀计算器。拍档的整数适合字符串 不同的类型,就是直接的数字不要用引号包裹,否则就成了字符串,不能用于数学计算。 拍档里的小数也有单独的类型,叫做浮点数,带小数点的数字都是浮点数,我带的是整数。 然后说说数学运算,首先是最常见的加减乘除,加和减在键盘上都有,但数学乘除符号在键盘上不能直接打出来,于是拍放的乘号用的是星号,除号用的是斜杠, 注意是正斜杠, shift 键左边那个不是之前当转一辅的那个反斜杠。所以如果我们要写一个一加二减三除四乘五,就会写成这样。五奖竞赛这个计算结果是多少,可以暂停 讲一下。如果你的答案是零,需要补一下运算优先级的知识。拍档的运算顺序和平时数学里的一样,都是先括号,然后乘方,然后乘除,最后加减 乘方。符号在拍档里是两个星号,如果要算二的三次方,就是这样写。 虽然我们说了拍档能做加减乘除乘方,但有些计算器还能做更复杂的,比如三角函数、 log 开方等。用拍档也能做吗?放心,代码是不会输的。 你首先需要导入一个叫 math 的函数库,你可以把每个函数库想象成一个工具箱,里面的每一个函数都是一个工具,负责一个功能。比如像我们熟悉的 print, 它 也是函数,负责提供展示或输出的功能。但使用 print 不需要你先首先导入函数库,因为它太常用了,拍档直接帮你默认放在里面了,这些默认就有的函数叫内置函数。 amat 是一个专门提供数学运算函数的库。 导入它的方法是在文件最开始一行写 import math, 然后你就可以用 math 加点,后面跟上函数名来使用它的功能。 比如计算 side 一弧度就写 math 点, side 括号里面放一,这个前面的 math 点是不能省略的,因为这个函数是属于 math 库里面的。那要如何知道这个 math 库支持哪些其他运算呢?你可以搜索拍 math 库官方文档,可以看到拍档给你列出这个库支持的所有函数,比如文档说 math 点 log 二,会返回以二为底的对数,那要知道以二为底八的对数的时候就写成 math 点 log 二八。 但如果你直接在编辑器里写一个运算公式,运行后你会发现什么输出结果都没有,原因是排放。虽然帮你计算出来了结果并存在了内存里,但他也只是在内存里,没有被后续使用,也没有被打印出来,所以你看不到他是什么值。 所以如果你要知道数学计算结果,可以用上 print, 或者是用某个变量进行复制,然后再 print, 就会展示出结果。现在是实践 时间,咱们的目标是写一个一元二次求根公式计算器 比如说要计算这个负 x 方减二 x 加三等于零的两个实数根,就可以用求根公式。这个公式我已经忘了,是现搜的,就是这个耳熟能详的。二 a 分之负 b 加减根号下比方减 cac。 那么在这个公式里面,我们的 a 就等于负一, b 等于负二, c 等于三。先在代码里面进行一下电量负值, 因为这里是加或减,有两个减,我们可以先分别计算,先计算这里是加法的那个减就是 副 b 加上根号,下面的是 b 方减四, ac 平方就是两个型号 减四乘以 a 乘以 c。 虽然数学公式里面这个乘法可以省略,但是在代码里面这个乘号是不可以省略的。 然后问题来了,这个平方根用代码要怎么写?平方根其实也相当于是二分之一次方,所以可以写成这个样子, 或者你也可以用 math 库,里面一个叫 s q r t 的函数也会返回平方跟结果在文档的这里有写。那如果我要去用这个 s q r t 函数, 那么首先我要在文档的开头 input, 然后在这里使用它的函数。酷的名字要先放在最开头,然后跟一个点,接下来是函数的名字,就是我们的 sq rt, 然后继续回到我们的公式,因为后面要做除法了,所以我们就把分数线上面的全部括起来,除以二乘以 a。 好的,这就是我们的第一个结,第二个结只需要把这里的加法改成减法就好了。下面就是见证奇迹的时刻,如果你运行一下,你就会发现啥都没有, 因为我们之前说了,你需要 print 才能看到结果。注意这个 print 也需要把整个运算给它包裹起来,然后再点击运行,这个时候你就可以看到输出的两个正确结果。 如果你想求另外一个方程,根本不需要更改公式,只需要更改上面变量的值。 比如我们如果再计算一个 x 方加九 x 加上二十等于零的值,那就相当于 a 是一, b 是九, c 是二十,直接运行。这里再次展示了正确的结果。 总结一下,用代码做数学计算有以下三个好处,第一个是可以看到整个公式, 随时检查,可以不用担心打错。第二个是可以很容易的改变变量的值,不需要重复介入公式。第三是如果公式复杂,你也可以通过中间变量来分步骤, 比如让这个 b 方减四 a c, 让它等于某个变量,假如说我这里让它等于 delta, 这样你这里就可以直接写 delta 的平方根, 输出来应该还是同样的结果。这样子的好处是让过程更加的简洁清晰。这次视频的知识点比较多,下个视频会轻松一些,我们稍后见。 有个说法是,程序员最怕的情况之一是代码刚写完的时候, 只有自己和上帝知道他是干嘛的,过了几天后就只剩上帝知道了。为了避免这种情况,人们写代码时一般还会加一些注释。注释就是会被解释器或编译器忽略的一行或多行文字,他是给人类阅读,而不是给机器执行的。 他的一个重要作用就是可以用来写一些代码思路的解释,帮助他人或未来的自己理解背后的意图。 拍葬里的注视用井号开头,在井号后面,你写什么内容,拍葬都不会管,你也不会执行, 但这个井号只管单行。所以如果你的注是跨了多行,每行前面都要加上井号。除了开头所述注是可以用来解释代码之外,有些时候你不想执行某端代码, 又不想删掉它,也可以在前面加上井号,达成跳过执行的效果。如果你那端代码很长,懒得一个个打,井号拍唱也有快捷键,选中那一整段代码,如果是 windows 按 control 和斜杠,如果是 mac 按 command 和斜杠 这样,那一整段代码前面都会被自动加上井号。如果你想撤销注视,只要选中,再按一次 ctrl 和斜杠或 command 和斜杠即可。 另外一个多行注视的方法是用三引号包裹住注视。你可能会想,之前的跨行字符串用的不也是三引号吗?是的,但是如果你不打印他,不用他复制或不对他进行任何其他操作,这就相当于那个跨行字符串没有任何 执行效果。没有任何执行效果的话,和注视也没有区别了。所以大家也会用三引号进行多行注视。注视这个东西,因为不影响程序执行,有些程序员会放飞自我随便写, 比如有求佛祖保佑无 bug 的,有血泪劝退其他程序员的注视,甚至引发过公关危机。一七年,有人发现佳美音乐程序员把免费 vip 用户注视为穷逼 vip, 引发用户不满。 后来程序员道歉,表示今后会正正经经写注视。因此还是建议不要在注视里过多放飞自我。我们下个视频见。 在现实的世界里,食物有不同种类,动物有不同种类,人也有不同种类。 在抽象世界里,数字也有不同种类。那么在拍档的世界里呢?拍档世界的物种叫做数据类型,包括字符串、整数、浮点数、 boy 类型、控制类型,以及后面才会讲解到的列表、字典等。 字符串类型 store 就是一串字符,表示文本内容,特点是会被双引号或单引号包裹。 你可以对字符串使用列函数,可以得到该字符串的长度。在字符串长度的计算中, 无论是空格数字还是符号,都会占据一个长度。但需要注意的是,如果是转异符,比如之前见过的反斜杠,后面跟 n 表示换行,这种情况下完整的转异符才占一个长度。你也可以提取出字符某一位置上的单个 字符,字符串后面跟上方括号,然后在方括号里面放锁引,就能提取出该锁引位置的字符。你可以把锁引理解为顺序,但和现实生活中不同,程序世界里是从零开始数,第一个锁引为零,第二个唯一,以此类推。 所以如果我要获得排在第四的字符,应该写的缩影值为三,这样会返回 l 字符。 整数类型在拍档里叫 int, 浮点数在拍档里叫 float。 针对他们的操作已经在之前的数学运算视频里覆盖过。由于数字写法和加减乘除等操作都很直观,就不在此追书了。 bo 类型, bo 只包含两种值,真和假。真在拍档里写为 true, 也就是英文的真。 注意, t 要大写,甲写为 false, f 也需要大写。波尔值虽然只有处和 false 两个值,但不久后学到逻辑判断时,你会发现波尔值的作用。当前只需要先记住有这么个种类。 还有一个非常特殊的数据类型,叫做空值类型 number, 这个类型下只有一种值, no, no 不是零,不是空。字不串,不是 force, 它表示完全没有值。如果你知道你需要一个变量,但还不知道这个变量的值,就可以先定义为 no。 当你不确定某个对象类型的时候,可以用 tt 函数,他会返回你该对象的类型数据。类型之所以重要,因为他决定了你能在该类型的对象上运用哪些函数。函数是 负责执行某个功能的,你给他合适的输入,他才会给你正常的输出。这就好比有个做巧克力的机器,你给他可可粉,他才能还你巧克力,你非要给他丢个石头进去,他就炸了。 比如练函数,我们已经知道他可以得到字符串的长度,但如果你把它用在整数身上,就会出现报错。除法也是在整数和浮点数上用很合适。给字符串用,拍到觉得这多少是有点大病,于是也会报错。 下面是实践时间。首先我们试一下对字符串球长度, 先定义一个变量,复制为 hello, 然后咱们就可以用 liam 对它求长度。如果此时你直接运行还是啥都没有,因为咱们还是需要用 print 函数来看它返回的值, 这个时候再运行就可以看到结果是十二,因为这个空格和符号他们都会各占一个长度。接下来试一下通过锁引获取前面字符串的单个字符。 永远要记住的是锁引是从零开始的,所以如果咱们要获取这个 h, 应该对他用锁引零取值,而不是一 in 的出来 运行成功获取到第一个字符,那最后一个字符的锁引是什么呢?因为整个字符串长度为十二,锁引从零开始,零一二三,以此类推。那么最后一个字符的锁引应该是十一。 print 出来看看, 可以看到成功的获取到这个感叹号,或者你也可以结合量函数,那么所以你就是自负串长度减一还是同样的结果。 然后我们试着定义一下 for 类型的数据,给变量 b 一复制为处,给 b 二复制为 force, 他们 都需要大写开头,如果你换成小写拍档,就不认这个是布尔值,可以看到已经出现了报错。然后你也不要用引号给它包裹住,否则就成为了字符串,咱们把它定义回到布尔类型, 接下来再定一个空值类型的点亮让 n 等于闹,这个开头的 n 也是需要大写的,否则排行是不认的。 现在为了验证之前定义过变量的类型,我们可以一个个使用 type 函数,比如 type, 咱们定义的第一个 s 是一个字符串,咱们打印出来看看,可以看到 就是字符串 story 类型,然后试一下 b 一 b 一,打印出来应该是布尔类型, 然后 type n, 因为 n 是一个空指类型,所以打印出来应该是一个 number。 你也可以对之前学过的浮点数或整数使用 tap, 比如 tap 一点五,因为这里有个小数点,所以它应该是浮点数 float 类型,而不是整数 int 类型。 最后我们试一下如果对错误的类型使用某个函数会怎么样。比如如果我们对固尔值 b 一使用赖函数, 此刻运行的时候可以看到拍档直接报错了。因此了解操作对象的所属类型还是非常关键的, 我们下个视频见。 python 有两种执行模式,命令行模式和交互模式。我们之前使用的一直是命令行模式,也就是写好命令后保存并运行整个文件。 运行的时候,拍档解释器会一行一行对文件进行解析和执行。正因为拍档解释器可以不读完整个文件就执行某一行命令,因此另外一种模式是交互模式,你输入一行后,拍档立刻执行并展示那一行的运行结果给你看。 交互模式的第一个好处是,你不需要创建任何新的文件,只需要进入交互式环境。比如点击 pitarm 下方的 pattern 控制台,或是在 windows 的 c, m, d, mac 的终端里输入拍档三,你可以看到他会给你展示三个间括号,这表示他在等待你的指令。 然后你可以输入任何你所知的拍档命令,比如 print high 回车,拍档会直接执行,并在下方展示出打印出来的字符串。 high 交互模式的第二个好处是,你可以不需要 print 语句,就能直接看到执行输出的结果。 举个例子,在之前命令行模式里,假设我们定义变量 a 等于你好加感叹号, 这之后要看 a 变量当前的值,你需要 print a, 但在交互模式里要看 a 变量当前的值,输入 a 回车后就能直接看到。再比如命令 进行模式中计算三乘二,你也是需要 print 三乘二才能看到结果。六、在交互模式中,拍档求职后,会直接把返回的六展示给你。 如果你要退出交互模式,可以进入 quit 括号,然后回车,或者你也可以直接按 control d。 虽然交互模式有以上好处,但我们平时更常用的仍然是命令行模式。原因很简单,交互模式里的命令都不会被保存。一旦退出交互模式,你就失去了之前介入的所有内容。 在一些人的理解里,交互模式就像是个游乐场,让你可以随便玩一玩,看一看,用最简单的方式测试测试命令输出的结果。像我有时需要做 一些一次性计算的时候,就会进入交互模式,输入算式得到结果,然后直接退出关闭。在别人还在找计算器的时候,来这么一套行云流水的操作还是非常装叉的,我们下个视频见。 虽然程序员是代码逻辑和运行结果的主要掌控者,但很多时候我们要从用户那里获得信息,并返回个性化的结果。 开放的 input 函数可以用来从用户那里获取输入,它的用法是 input 括号,然后里面放字符串,作为给用户的提示信息。 现在你应该已经了解了函数名后面跟括号,然后在括号里面放上参数,也就是要传入的数据是标准的调用函 输的方式。那么 input 具体可以怎么用呢?比如你可以问用户的年龄,那么运行时排档就会展示出你放进括号里面的提示,并且开始等待用户的输入。 比如用户可以输入二十,然后回车表示输入结束, title 会继续运行之后的代码, 但这样我们并不能知道用户到底输入了什么。还好 input 函数在用户输入完后会把内容进行返回,所以我们应该用一个变量去获取 input 函数返回的值, 那么在这之后,你就可以利用这个变量进行一系列后续操作。另外一点需要注意的是, input 一律返回字符串,即使你输入的是数字,他也会当成字符串来看待。所以如果你直接拿 user 去做数学运算,拍档会报错,那怎么办嘞?拍档也有函数,能把字符串 story 类型转换成整数, inter 类型就用一个叫 inter 的函数,比如 inter 六六六,会返回整数六百六十六。 当然,你往里面传入的参数应该确实能被转换成整数,否则就会报错。类似的 flow 函数可以把其他类型转换成浮点数,然后 store 函数可以把其他类型转换成字符串,这在你需要打印的时候很有用, 比如整数不能和字符串连接在一起,打印把它转换成字符串后就行了。那么在我们的例子中,如果要用年龄进行数学运算,就可以用 int 函数转换成整数先,如果还要打印出来,用 star 函数再把计算结果 转换成字符串,那么用户输入二十回车拍档会打印出应十年后会是三十岁。下面是实践时间, 我们可以用 input 帮用户做个简单的 bmi 指数,也就是身体质量指数的计算器,它的计算公式是, bmi 等于体重除以身高的平方,其中体重的单位是千克,身高是米。 首先我们定义变量 user v, 让它等于用户输入的体重。这里给用户一个提示,比如请输入您的体重 单位是千克, 然后定于 user height, 让它等于用户输入的身高,单位是米。接下来定义 u c, b, m, i, 它就等于体重除以身高的平方。 这里可以看到智慧的拍唱已经在提示你问题所在了。现在 user wait 和 user hide 都是字符串,所以不可以用除法和平方去计算,我们要先把他们两个给转化成数字。 这里我们还不能对身高用 in 函数,不然大家都成一米高了。所以我们可以用 flow 的函数先把字符串给转换成符点数, 这样就可以计算出 bmi 值。最后我们可以为用户 print 出来计算的结果, 如果我现在这样写,他也会报错,因为别忘了还要把这个数字转换成字符串才能打印,所以我们再利用一下 star 函数,现在就可以运行一下,试试随便写个数字 运行成功。现在这个简单的计算器就可以计算出任意身高和体重的 bmi 值,我们下个视频见。 但凡有点情商的人,日常生活中每天都在做条件判断, 比如男生可能根据女朋友的情绪判断今晚能不能打游戏,员工可能根据老板脸色判断该不该提加工资,通过判断条件是否满足来决定。执行的内容就是条件语句的核心。 拍档的条件语句结构是这样的,首先是 if 表示,如果后面跟条件只要求值出来为布尔值,也就是 true 和 false 都可以作为条件。 比如如果你定义某个变量的值是不二值,那它就可以作为条件。举个例子,定义变量 is happy, 把它复制为 true 或 force, 那么这个变量就可以放在 if 的后面作为条件。另外你也可以结合比较运算符,比较运算符包括等于 号用来比较两个对象的值是否相等,比如三等于三会返回 true, a 等于 b 会返回 false。 注意这个比较运算符是两个等号,因为一个等号已经被变量负值语句用了。 另外还有不等于号,用于比较两个对象的值是否不相等,比如 a 不等于 b 会返回去。 然后还有大于号、大于等于号、小于号、小于等于号。含义和数学里面那些比较符号都差不多,像五大于等于二十,就可以作为条件放在 if 的后面,因为值为 false 是不二之。 你需要注意的是,条件后面还有一个冒号,表示条件结束,下方是条件为真实需要执行的语句, 这个语句前面需要有缩进,建议缩进为四个空格语句,也可以为多个。所有 e 下方前面有缩进的语句都会被看成条件为真实要执行的内容。 如果你希望条件为假时什么都不做,条件语句到这里就可以结束了。但如果你想在条件为假时执行另外一些语句,那么就跟上 ls。 冒号下方为条件为假时要执行的语句。 再一次,语句可以不止一句,但每行前面都要有缩进,因为拍档会根据缩进来判断这行到底是 if 管的部分还是 else 管的部分,还是压根不属于这一整段条件语句下面是实践时间,我们可以结 和 input 写一个判断今晚打游戏对象会不会生气的程序。首先定义一个变量, mood index 表示心情指数,让它复制为 input 函数的返回值,对象今天的心情 辛勤指数是,接下来我们就要用这个值来判断今晚能不能打游戏。假设辛勤指数大于或等于六十,就说明还可以能够心平气和的容忍你打一晚上游戏, 那么这个时候我们可以 print 出来。恭喜,今晚应该可以打游戏去吧皮卡丘 写到这里就可以结束了,因为如之前所说, x 那部分是可有可无的,但现在这个程序其实是有问题的,因为不要忘了,音破的函数返回的值一律是字符串。 我们如果要把木的 index 这个字符串和数字进行比较,就得把木的 index 也转换成数字线,所以我们这里还是使用 in 函数把它转换成数字, 然后我们可以把 s 部分也加上 s。 冒号回车还是不要忘了缩进,虽然拍唱会自动帮你缩进这里也可以,还是拼的出一句话, 为了四个条命,还是别打了。运行这句话 的条件就是当 mood index 大于等于六十为 force 的时候,其实也就是相当于 mood index 小于六十的时候。现在我们就可以运行一下试试。 先输入一个心情比较好的数字,比如八十五,可以看到打印出今晚可以打游戏。 我们再次运行一下,试试输入一个心情不咋好的数字,比如二十,答应出还是别打了。另外之前也说过,这些语句可以不止一行,只要你记得正确的缩进就行。比如,如果可以打游戏, 我这里还可以加一个表情,表示雀跃的心情。如果你这里没有缩进就会有问题,因为拍 拍档一看这句话前面没有缩进,说明你的条件语句已经结束了,那么这句不管怎么样都会 print 出来,然后下面他又看到一个 l, l 是不可以独立于 if 存在的,所以拍档会给你报错。现在我们改正一下缩进,再运行一下试试。 输入九十,可以看到第二句也被打印出来了,我们下个视频见。 上回书说到,通过判断条件是否满足来决定执行的内容就是条件语句的核心, 拍放的条件语句,在条件为真时,执行 if 下方的语句,在条件为假时,执行 else 下方的语句。但有时候一个条件并不足以决定执行行动,比如 一般你对象心情不好的时候,你是不敢屁股对着他打一晚上游戏的,但如果他心情不好的同时找朋友玩去了,不在家,那你仍然拥有打游戏自由权。 这种情况下就可以用嵌套条件语句。嵌套条件语句就是在条件语句里面再放条件语句。 比如可以先写一个 if 语句,然后再缩进,之后再写一个 if。 那么如果要下方这个语句 a 被执行,首先需要满足条件一为证,否则根本不可能执行到里面这个条件二的判断。 其次他还要满足条件二也为证,不然也不会被执行。我们可以继续给里面这个条件语句配一个 s, 那这下方的语句 b 也是。首先必须满足条件 a 采用 有可能进入条件二判断,然后条件二为假。所以 out 下方的语句被执行嵌套时,更需要注意缩进拍放的缩进一般为四个空格,属于该 if 或 out。 下方的语句都会比那个 if 或 out 再多出四个空格, 拍档会根据缩进判断属于哪个条件分支。针对条件一,我们也可以配一个 s, 这个语句是否执行就只取决于条件一,只要条件一为假,就会被执行。 如果我们用欠套条件语句表达开头所说的例子,就可以这么写,如果对象心情指数小于六十,判断他当晚是否在家。如果在家条件为真,就不能打游戏,否则就拥有自由。除了欠套,我们还可以使用多个 条件判断进行更加细致的行动划分多个条件判断的关键词是 lif, 基本结构长,这样,拍档会依次判断各个条件,直到找到第一个为真的执行里面的语句 l leave 的数量你想要几个就可以有几个,没有上限也没有下限,这种结构相比前面的嵌套更加的清晰和直观。由于拍档是从上往下执行,他只会执行第一个满足条件的语句,比如如果条件二和条件三同时满足, 拍档也只会执行 l leave 条件二那行下方的语句,因为一旦进入那个分支,就不会再看同一层级下的其他条件判断了。下面是实践时间,我们可以结合多条件判断,丰富一下 之前写的 bmi 计算器。首先把之前拍放 input 视频里面计算 bmi 值的代码抄过来, 如果你忘了之前代码的意思,其实这里就是获取用户输入的体重和身高转换成浮点数,然后用变卖的计算公式,体重除以身高的平方,然后把计算结果打印出来, 那么根据成人 bmi 的划分标准计算结果,小于等于十八点五属于偏瘦。大于十八点五且小于等于二十五属于正常。大于二十五且小于等于三十属于偏胖。大于三十属于肥胖。 我们可以通过多条件判断为用户输出划分的结果。首先如果 user bmi 小于等于十八点五,输出四, bmi 值属于偏瘦范围。 如果我们只有小于等于十八点五和大于十八点五这两种情况,那么下一行用 s 就可以了。但因为现在我们有多个划分范围,所以需要用到 l 令。 那这个条件应该怎么写呢?在数学里面可以这样,把变量放在中间,用两个小于或小于等于号一起表示范围,这种表达方式在拍档里也是可以用的, 所以我们可以直接把它作为条件,然后输出此变卖值属于正常氛围。 下一个还是一样 l leave 后面跟上。如果它大于二十五且小于等于三十,输出此 b m i 属于偏胖范围。 最后一个条件,因为如果前面的所有条件都为假,正好说明 bmi 值大于三十,所以最后一个条件我们可以直接用 else 表示。如果前面条件都为假,那么输出此 bmi 值属于肥胖范围。 现在我们就可以运行来试一下,随便输入一个体重,再随便输入一个身高,可以看到他已经给你输出了正确的 bmy 分类。 如果你还想丰富一下这个计算器,可以尝试一下用嵌套,比如可以根据用户性别输出。先生您好或女士您好,此 bmi 值属于叉叉范围,这个可以作为课后作业,大家练习一下,我们下个视频见 上回书说到。我们可以用嵌套对多个条件进行判断,比如如果对象心经指数小于六十,判断他当晚是否在家。如果在家条件为真,就不能打游戏,否则就拥有自由。两个 if 条件与之嵌套起来,就能完整表示出这样一个情况。 但有些复杂情况下涉及的条件更多。比如我们假设如果要对象心情大好,奖励你个 switch 作为新年礼物,需要满足,一个月内主动做家务次数超过十次, 发红包次数超过一次,陪逛街次数超过四次,一个月内没有惹他生气过。如果这个要用欠套来表达,代码就会看起来非常的不优雅,因为缩进层级多了后容易让人迷失,那么逻辑运算此刻就能派上用场。 拍档的逻辑运算符号只有三个,分别是 and、 or 和 not, 也就是中文里不好运算的雨或菲。 更通俗来说, and 可以理解为,并且,比如 x 大于五 and x 小于十就是 x 大于五,并且 x 小于十。 or 可以理解为,或者,比如 x 大于五 or x 小于十就是 x 大于五,或者 x 小于十, not 就是不。比如 not, x 大于五就是 x 不大于五。你可以用 and 连接两个或以上的操作对象, 只有所有的都为 true, 才会返回 true。 只要有一个或以上为 false, 最后求知结果就是 false。 哦,也一样,可以连接两个或以上的操作对象,其中只要有一个或以上为 true, 就会返回 true。 只有当所有都是 false 的时候,才会返回 false。 not 则只能用于对一个操作对象进行运算。它的特点是,如果原先的操作对象是 true, 它会返回 false, 原先的是 false, 它就会返回 true。 闹得非常直观,把原先的不尔之反过来就行了。 and 和 or 如果你觉得自己记不住的话,可以这样想,先把 true 想象成开心的事情, thought 想象成不开心的事情,那么 and 就像是一个悲观的人,只要有一件事情不开心,他就会返回不开心。 or 像是一个乐, 乐观的人,只要有一件事情开心,他就会返回开心。逻辑运算符也是可以混用的,但混用时需要留意运算优先级。 note 的优先级最高会首先被求值,然后是 and, 最后是 or。 当然,你也可以通过括号改变运算顺序,这和在加减乘数等数学运算上的用法一样, 如果结合逻辑运算表达最开头那个例子,我们可以这样写,可以看到这比用嵌套要直观和优雅很多,但逻辑运算也不是在所有情况下都会比嵌套更优雅,也需要具体情况具体分析,我们下个视频见。 如果打折季快到了,你想记下有哪些要剁手的?应该怎么做呢?假如, 假如你想买俩东西,我们可以定义变量, item 一, item 二,复制为你想买的第一个东西,第二个东西。但如果有十个东西要买,要定义十个变量,一个个复制太麻烦了。 为了优雅的解决以上问题,我们需要一个数据结构,把相关联的数据整合在一起,拍同的列表就能达成这个目的。 一个空的列表用一对方括号表示,如果要在列表里面放多个数据,就用方括号把它们包住,用逗号在之间进行分隔。 如果要往定义好的列表里面加东西,可以用一个针对列表的方法,叫 append。 方法和函数差不多,都是用来负责某个特定功能的。不同的是,在使用时,方法一般在操 对象后面加点方法名,括号这样被调用,而函数是函数名括号里面放入操作对象。还要明确的一点是,列表和字符串、整数、小数、布尔值。这些数据类型有一个显著不同, 那就是列表是可变的,而刚才说的那些不是啥意思嘞。以不可变的字符串为例,如果我们想把这个字符串转换成大写的打印出来,有个叫 upper 的方法可以用, 他会返回一个把原先字符串字母全变成大写的新字符串,但是原先的字符串还是他本身没有任何变化, 所以如果要把 s 全部变成大写,还需要把新的字符串再复制给变了 s 才行。但列表是可变的,并且 ipad 方法会直接改变 原列表,往列表里面加元素。因此用 apend 的时候不需要也不应该再对 shopping list 重新进行复制,因为原先的列表已经被改变了。 要删除列表里的某个元素,可以用 remove 方法,括号里面放该元素的值,此处也是直接调用 remove 就会在原列表上生效,不应该对变量重新复制。 用 remove 时,该元素也得确实存在于列表里才行,否则就会报错。你可以随时打印列表,查看里面都有哪些元素。 拍放的列表还可以放不同类型的数据,这点和许多语言都不一样,使用起来很自由和灵活。背后的原因和底层时间有关。列表和字符创一样,都可以通过练函数求长度 内函数会返回列表里元素的数量。针对列表,你也可以通过锁引获得某个位置的元素。列表的锁引同样从零开始数最后一个元素的锁引为列表长度再减去一。 如果你要修改列表里的某个元素,可以利用锁引复制,直接覆盖该位置原本的元素 拍档。还有很多可以针对列表的内置函数,比如 max 面函数可以返回列表里面的最大值,最小值。 sorry 的函数可以帮你把排序好的新列表返回给你,同时不改变原先的列表。这些函数在实际开发过程中非常有用,还有更多奇迹引巧等你探索。下面是实践时间,我们还是用购物清单的例子实际 操作一下。先定一个空的列表叫 sharpen list, 空列表用一对方框号表示。假如列表上前两个是键盘和键帽,我们可以使用 ipad 方法添加这两样东西。 用 print 打印出来看一看,可以看到两个字符串都在里面。 如果要把键帽从列表里面删除,可以用列表名点 remove 里面放他的值。再打印出来看看,现在键帽就已经不在里面了。再往里面放一些东西试一试, 比如可以加一个音响,再加一个电竞椅, 此时可以用乱函数输出,看一下里面到底有多少的元素 输出,正确结果为三。如果你想获得某个位置上的元素,可以利用锁引,比如只看排在第一个的物品是什么,可以用 print 列表明方括号零, 这样排在第一个的元素就被打印出来了。假如你刚刚发现自己没钱买音响,只能换成硬盘,也可以用锁引把第二个元素更新为硬盘。注意第二个元 元素它的缩影值为一。现在再打印出来看一下,原先的音响已经被覆盖成了硬盘。 假如你还定义了一系列的价格列表,比如有键盘是七百九十九,显示器一零二四,硬盘两百,电竞以, 比如说是八百。然后我们就可以用 mac 函数获取列表里面的最大值,最小值也可以用命函数来获得。 以及如果你想要给价格从小到大进行排序,也可以用一个 sorcher 的函数里面放上列表,它会返回 排序好的新列表。然后我们把刚才这些都 print 出来看一看,打印出 max price, 然后最小的价格以及排序好的列表, 可以看到代码可以帮你把找最大值,最小值以及排序这些活都做了。我们下个视频见。 如何用代码实现一个通讯录。通讯录的特点是可以用人名查找到对应的手机号,用变量可以勉强实现这一点。 比如存小明的电话就给变量风 number of 小明复值。存小花的电话就给变量风 number of 小花复值。需要谁的电话的时候 拼的出来该变量就好,但问题是这样太不规整,人多了以后电话号码东一个西一个的。于是现在思路变成了,我们还需要一个能统一把电话号码装进去的数据结构。 之前学的列表怎么样呢?用列表的话,我们就有了这样一个通讯录,但一串电话号码根本不知道谁是谁的,这连通讯录的基本目的通过名字查电话号码都做不到。 如果我们可以把人名和电话号码绑定起来就好了。字典 dictionary 这个数据结构可以帮我们实现。 字典用于储存键值对键的英文是 k, 值是 value, 键会有对应的值,键是用来查找值的。这和我们现实生活中的字典很像,我们查字典的时候,通过 字作为见来获得作为值的示意。空的字典用一对花括号表示,要在字典里面放入多个见值对,就用花括号把它们包住。见和值之间用引号表示,对应见值对之间用逗号分格。 如果我们要获取某个键的值,在字典名后面跟方括号里面放入键,需要注意的是,键的类型必须是不可变的,列表属于可变数据类型,就不能作为键,而字符串、整数、浮点数等就可以。 那你说通讯录里面有三个张伟,就是同时需要名字和年龄才能区分列表又不能作为见,咋办嘞?拍档贴心的为我们准备了一个不可变但又很像列表的数据结构,原组 top 圆组里面可以放多个元素和列表肉眼可见的区别是,列表用方括号,圆组用圆括号。 另外,由于原组不可变,添加、删除元素等通通不能操作,虽然很不灵活,但他能帮我们实现往字典里存三个张伟的愿望。 此时这些元组就是字典的键,找电话号码时就能把整个元组作为键。字典和列表一样,也是可变的,所以可以添加和删除键值对。 比如你在街上找个陌生美女,要到了电话号码,要添加进通讯录的话,可以用字典名方括号里面放他的键,然后复制为该手机号字符串,这样字典里就会多出一个键值。对,但需要注意, 更新值也是一样的操作。比如如果美女 a 这个键已经存在,那你刚才做的就是把它原本的值覆盖了,获得了一个号码的同时失去了一个号码。 如果想知道某个键是否已经存在键赢,字典会返回一个布尔值,告诉你该键是否已经存在于字典里,存在返回处,否则返回 false, 要删除一个键值。对,可以用掉掉自点名方括号里面放入键,就可以把键和对应的值从字典里删除,但如果键本身不存在的话就会报错。 如果你想知道字典里有多少件之对赖函数,这个老方法对字典也管用。下面是实践时间, 我们可以用 字典来做个查询网络流星语含义的电子词典,这个练习会结合字典以及之前学的 input 和 if 判断。你可以在网上随便搜索一些流星语词条。 首先创建一个空的词典,我们也可以在这个词典里预先放上两条内容,方法是键冒号,然后跟上键对应的值, 所以这里我就把第一个词条复制过来, 下一个键值对,用逗号进行分格。这里建议进行一下换行,因为它比较长,换行之后每个词条之间也会更加的清晰,然后还是见 冒号直。 现在我们就创好了一个长度为二的字典,然后把接下来的流星雨以及他们的示意依次添加到词典里,添加方法是字点名方括号里面放入键, 然后对它进行复制。 现在我们的字典里就有三条内容了,添加的有点慢,我要动用一下剪辑魔法了。好了,现在我的词典里有十条内容了,可以开始做查询功能了。我们的查询功能是这样的, 首先询问用户,请输入您想要查询的流星雨, 还要记得把它复制给一个变量,不然我们是获取不到用户输入的值的。 我们需要知道这个查询的词条是否在我们的词典里,这里我们就用 in 去进行判断。如果词典里有这个键, 就先给用户打印出来,先打印一句您查询的这个词含义如下,然后我们为用户打印出这个词的意思。那怎么获取 carry 的 示意呢?就是字典名方框好,然后建名,但是这里我们是一个变量,所以我们在这里放入 carry, 这相当于是用用户输入的内容去查询他在字典里面对应的值。 那如果查询的那个词不在词典里,我们先为用户打印出您查询的流星雨暂未收, 然后我们再告知一下用户我们的词典当前收录了多少个词条。这里提醒需要用到赖函数, 当前本词典收入词表数为,要获取字典的 长度,用练里面放入字典的名字,但是这里需要注意的是,练返回的是一个整数,所以我们需要还要把它转换成字符串,这样才能和之前的字符串进行拼接。 现在我们运行一下试试。 假如我要查一下 y y d s 的意思,可以看到他已经成功的把 y y d s 的意思给我打印出来了,因为我这里有这一条, 现在试一下一个不存在的流星雨,随便打一个可以看到他也告诉我了您查询的流星雨暂未收录,以及成功打印出来当前的词典里面 有多少条内容,我们下个视频见。假如你有全公司上万人的体温自测报备信息,需要找出来有没有人体温高于三十八度,一条一条看的话,估计等你找着的时候疫情都结束了。 在拍档里我们可以用负循环进行迭代,迭代的对象可以是列表、字典、字符串等。对列表进行迭代就是按顺序对里面各个元素做一些事情。 对字典进行迭代,就是按顺序对里面的各个键或直。做一些事情,对字符串进行迭代,就是按顺序对里面各个字符做一些事情。 python 的 for loop 基本结构长这样,先是关键词 for 空格,然后自己取一个变量名来代表迭代对象里面的每个东西。 接下来是关键词 in, 后面跟上迭代的对象。以检查体温列表为例,可以写成这样。 其中 temperature list 是已经定义好的包含全公司人员体温的列表,而 temperature 是自己起的变量名。其实具体叫什么无所谓,不管叫什么,这个变量名会被依次复制为列表里面的每一个元素,一直到最后一个。 针对每个元素的操作,写在复位的下面一行,所有前面带缩进的都会被视为这个复循环里面的语句对每个元素都会执行一遍, 比如检查每个体温数字,如果超过三十八度,打印完球了就可以这样写。这样你只需要看打印出多少个完球了,就能知道有多少人发烧了。但这样并不能知道具体是谁发烧了。 如果我们还有一个以工号为键,以体温为值的字典,利用复循环就能筛选出发烧的人。拍档的字典有这样三个方法,字典名点 kiss 会返回里面的所有键,字典名点 values 会返回里面的所有值。字典名点 items 会返回里面的所有键值。对, 我们可以用复语循环结合 items 方法把发烧的人的功号打印出来。这里复循环后面跟了两个变量。因为字典名点 items 在复循环时,变量会被复制为键和值组成的元组。 这种写法相当于把原组的第一个元素复制给 staff id, 第二个复制给 temperature。 如果你觉得这样不够直观,他的意思和这种写法是一样的。执行这段程序就会帮你秒找出所有体温高于或等于三 三十八度的员工的工号。负循环结合 range 还有奇效,大数学家高斯在小学时被老师出题计算从一到一百数字的和,当场想出了和等于首项加尾项乘以项数除以二的公式,得出五零五零。这个结果 没有高斯那么聪明的,我们别说手算,就是用代码打一加二加三加四,一直加到一百都挺累人的。复循环节和认知的作用就在这个时候体现出来。 range 用来表示整数数列括号里面第一个数字表示起始值,最后一个数字表示结数值。需要注意的是,结数值不在序列的范围内。 比如 for i in rent, 五十 i 会依次被复制为从五到九的数字,但不会为十。 rent 还可以包含第三个参数,表示不长, 也就是每次跨几个数字,如果不知名的时候默认为一。比如,如果要答应一到九之间的所有基数可以写成这样。那么高四的那道小难题算出从一加到一百的和,咱们也能秒算出来了。 这里第一行先定义一个变量,用来储存之后的一加二加三,一直加到一百的结果。然后在负循环里,第一次循环 i 被复制为一,所以偷偷变量被加一, 第二次循环被复制为二,偷偷变量被加二,以此类推,一直等到 i 等于一百,偷偷变量被加一百,然后循环结束,打印出偷偷的值得到我们想要的答案,我们下个视频见。 假如你想用相机捕捉日落的整个过程,要懒得一直盯着, 于是决定选一个自动化程序,持续拍照拍照拍照,直到天空亮度小于五百。但这要怎么写呢?假设我们有个用来测量当前天空亮度的叫做 measure brightest 的函数可以用。 如果只用这个 if 判断,会出现一个问题,那就是这个程序只会进行一次判断,最多也就照一张照片,捕捉不到全过程。 那如果我们用负循环重复执行 if 判断呢?这样会执行一百次判断,感觉比之前那个靠谱,但由于计算机运行极快,循环一百次也很可能撑不到日落结束。 当前摆在我们面前的难题是, if 判断要进行多少次后,条件才会为假?我们不知道,但没关系,挖耳循环会踏着 七彩祥云前来拯救我们。他的基本结构长这样,外有关键词后面跟上一个条件,只要求值出来为布尔值,也就是处或 force 都可以作为条件。 计算机会判断这个条件 a 是否为真,如果为真,执行下方缩进部分的内容,然后再次判断条件是否为真。如果为真,执行行动 b 如此循环,直到条件为假,退出循环。 如果 y 后面的条件 a 在第一次判断的时候就为 force, 那么行动 b 一次也不会被执行。 用外耳循环写我们的拍日落程序就很容易了。这个程序会在当前天空亮度大于或等于五百的时候持续拍照片,直至亮度小于五百。这个例子说明,在条件核实结束未知的情况下, yo 循环比否循环更适合使用。不过除此之外,很多时候 yo 循环和否循环可以互相转换。比如以下三段程序都是在打印出列表里面的每个元素, 第一个用的是简单直白的放循环,第二个用的是放循环和 range 的结合。锐志里面只放了一个值,这种情况下,起始值默认为零,结束值为放入的那个值,即这里是类似的一的长度, 那么爱会被依次复制为零、一、二等,直到为类似的长度再减一。零是列表里第一个元素的缩影,长度减一是列表里最后一个元素的缩影, 所以这段程序也相当于打印出列表里面所有元素。第三个用的是 while 循环,最开始 爱的初始值为零,由于零小于列表长度,进入循环,打印出第一个元素,然后爱的值被加一后成为二,再次进入循环,打印出第二个元素,一直循环,直到爱变成列表长度。 此时由于 i 小于 land list 一条件为假,退出循环。从这三段来看,在既可以用 for 循环,也可以用 yo 循环的情况下, for 循环会更加简单直观,所需函数更少。而且 while 也比 for 更加危险一些。 比如,如果你忘记写对爱进行递增的这行条件,很可能进入无限循环,因为爱会一直等于零。外要后面的条件可能一直都为正。但也有些情况,外要循环可以做负循环做不到的事情。比如开头 的例子。总结一下,复位循环在有明确的循环对象或次数的时候更方便,汪小泽更加通用,特别是不知道需要循环多少次的时候。下面是实践时间, 我们可以利用 while 循环写一个对用户输入数字求平均值的计算器。这个计算器的特点是用户可以输入任意数量的数字,最后输入 q, 表示所有数字输入完成,然后程序给出平均值计算结果。 此时你可以先暂停,自己试一下,把它写出来,然后再播放视频,看我的参考代码。 首先我们让我们的计算器 print 一句,哈喽呀,我是一 个求平均值的提示,然后从用户那里获取 input 输入数字,并且提示一下,完成所有数字输入后,请输入 q。 然后我们还要记得把这个 input 返回字符串复制给一个变量,不然就拿不到用户输入的结果。 那么现在的问题是,如何实现持续从用户那里获得输入,直到用户输入了 q 呢?这种一直做某件事情,直到某条件为假的情况就非常适合用 while 循环 user input, 这里应该是等于 q 还是不等于 q, 可以想一下,因为我们是要他不等于 q 的时候继续循环,所以这里应该是不等于 q, 然后我们就可以去获得用户的下一个输入,把这一句再复制过来一下,现在先运行一下试试。 可以看到,当输入结果不为 q 的时候,程序就会继续从用户那里要输入,但如果为 q, while 循环就会结束,程序完成执行。 现在最关键的逻辑已经有了,下一步就是如何把平均值给计算出来。计算平均值,我们要知道数字的和以及数字的个数,平均值就等于和 和除以个数,那么可以先定义一个 toto, 去记录和以及看去记录个数。接下来我们可以每获得到用户的一次输入,就把和以及个数都增加一下,但这个增加操作应该放在什么位置呢? 可以确定的是,它应该在外循环的里面,否则只会被加一次。如果我们放在这个 user input 的后面,那么第一次获取到的 input 数字就没有被加进来。而且如果用户在这一次里输入的是 q, 我们把 q 去加上 toto, 程序就炸了, 所以他应该出现在这个 input 的前面。先把用户输入的内容转换成小数,然后把 total 加上这个数字, 这行其实也可以把它简写成这样, total 加上等于 number, 这和 total 等于它自身再加上 number 是完全一样的意思,所以我们把它删掉, 然后 count 等于四声再加一,这行同样也可以被简写成 count 加上等于一。所以这里我们也用更简单的方式,这个程序已经能够获得用户输入数字的和以及个数了。接下来就是计算出平均值, result 等于 total 除以 count, 现在似乎只差最后一步打印出来 print 零输入的数字平均值为。 不过这个程序还有个隐患,如果用户在第一次就直接按 q 终止掉程序的话,实行到这里程序就会炸掉。 因为 total 它的原始值是零, count 它的原始值也是零。到了这里零除以零在数学里面是不被允许的,所以拍档也不允许这样做会有报错。所以我们还需要进行以下判断,如果 count 是零,我们直接让 result 也等于零,否则才等于 total 除以 count。 现在再运行一下试试,随便输几个数字, 然后 q, 可以看到这里已经打印出了正确的平均值。我们再试一下,第一次运行的时候就输入 q, 这里也打印出了正确的平均值。我们下个视频见。 要减少春节群发祝福短信的敷衍感,最简单的招式就是在内容里面插入人名,这样会显得更诚恳,因为打起来也更麻烦。当然,作为会写代码的我们来说,这不是一件麻烦事。以这条短信为例,有两处需要填入名字的地方, 有了联系人列表,我们就可以用一个负循环把这些名字拼接到正确的地方。由于这行代码比较长,我们用反斜杠进行换行。假如我们还有个可以根据联系人名字发出短信的函数叫 set message, 现在这段程序就会自动生成短信内容,并发给对应联系人。现在假设有个更复杂的情况,我们有条短信不只想自动替换联系人名字,还想把生肖也给替换了。 比如虎年就是虎年大吉,兔年就是兔年大吉,这样就可以一辈子都用这条祝福内容,那这段程序就会被写成这样。读下来后,你有没有感觉到好好一个短信被写的稀碎,老在中间被加号打断,非常不直观和连贯。 拍档提供了两种方式,更加简洁优雅的格式化字符串。第一个是 format 方法,可以把 message content 写成这样,花括号表示会被替换的位置,里面的数字表示会用 format 里面第几个参数进行替换, 这里零表示第一个参数, year 一表示第二个参数 name。 在因而为虎, name 为老林的时候, message content 就会长这样,现在一个完整字符串就可以搞定,短信内容读起来舒服很多。 用 format 还可以根据关键词而不是位置来指定进行替换的对象。这种情况下,生肖和人民的位置就无所谓了,只看 format 里的关键字。比如关键字 current year 给的值是 year, 所以所有为 current year 的地方都会被替换为 year 变量的值。 更简洁的话,可以把 ear 和 name 变量迷也重复用到字符串里。只要你能分清等号前面的是关键字,对应花括号里面的关键字,等号后面的是参数值。除了使用佛麦的方法, 还可以用 f 字符串在字符串前加前缀 f 花括号里的内容会被直接求职添加到字符串内。比如英语变量当前的值是虎, name 是老林,这段代码也会产出我们想要的效果。 除了用字符串进行格式化之外,数字也可以对字符串进行格式化。比如我们有个学生名和对应记点的字典,虽然 gpa 是符点数,但用 format 方法的时候,不需要手动转换成字符串,就可以打印出记点信息。 另外,你还可以用冒号点数字 f 来指定浮点数,在格式化时保留几位小数,比如打印出的记点只保留两位小数,就在后面跟上冒号点。 on f 用 f 字符串的时候也是一样,在 括号里面的表达式后面跟着冒号点。二 f 所有基点都会被保留两位小数,我们下个视频见。 假如我们要写个程序计算扇形的面积,并且打印出来。扇形面积的计算公式是圆心角度数除以三百六十乘以 pi, 再乘以半径的平方。 如果派取近四至三点一四,当圆心角为一百六十度,半径为三十的时候,这段程序会被写成这样。 如果我们的程序里面在多处都需要计算不同扇形的面积,就会出现一堆类似的代码,唯一不同的是,带入公式的角度和半径不一样。软件开发原则里面有一条叫做拽原则, don't repeat yourself, 不要重复你自己。也就是说不要做代码复读机,自己拖重复的代码就违反了拽原则。 函数可以帮助我们远离复读机行为。我们很早就见过函数了,比如 print some type, 这些都是拍档自带的函数,每个函数都负责完成某项特定任务。使用函数的时候,我们用函数名括号,括号里面放入想要传入的参数来进行调用。 但我们不仅可以调用函数,也可以定义自己的函数。我们可以把定义函数想象成是制作一个负责某一特定任务的机器, 一旦制作好后,当你再需要完成那个任务的时候,直接用那个函数就好了,不需要再反复定义。比如我们先试着定义一个计算第一个扇形面积 的函数,首先是大夫,关键词表示开始定义函数,后面跟上函数的名字,括号冒号。然后还是我们熟悉的缩进,又要划分哪些代码属于这个函数的定义范围。 接下来我们可以把之前计算第一个扇形面积的代码全部搬进这个函数的定义里面,现在这个函数就定义完成了。 需要注意的是,定义函数的时候,里面的代码都不会被执行,只有在调用函数的时候,才是里面代码被实际执行的时候。 现在每当我们希望打印出第一个扇形面积的时候,只需要简单的一行代码函数名括号来调用这个 calculate sect 一拍档就会逐行执行函数定义里面的代码,打印出第一个扇形的面积。 但这个函数还有点问题,虽然说要重复打印第一个扇形面积时,我们可以直接用这个函数,但如果我们想要打印出第二个扇形的面积,要再定一个 calculate sector 二吗?这仍然会带来一些类似的重复代码, 我们可以通过参数让这个函数变得更加通用。这就好比你有个做包子的机器,最开始你只想吃猪肉白皮大包子,这个机器你一按开关就会给你个猪肉下大包子。 但后来你发现你还想吃韭菜馅紫皮包子或者牛肉馅绿皮包子。于是你换了个更通用的机器,这个机器接收肉馅和面粉,你给他牛肉,他就是牛肉馅,你给他紫色面粉,做出来的皮就是紫色的。这就比一个只能做猪肉馅白皮包子的 机器更灵活。回到我们计算扇形的函数,先把变量名里面的一全部去掉,因为这个函数不只针对第一个扇形,然后在括号里面放入圆形角、角度和半径这两个参数。 一旦我们给了这两个参数,就不需要对变量进行复值了,可以移除掉这两行。因为我们在调用函数的时候,这两个参数会像变量被复制为你传入的值。现在我们就收获了一个可以计算并打印出任意圆心角和半径的扇形面积的函数。 这几大坨代码在我们定义好自己的函数后,都可以被压缩成这样,简洁优雅。但这个函数还可以做的更好,具体哪里好,请听下回分解,我们下个视频见。 在上个视频里,我们定义了一个可以计算并打印出任意圆心角及半径的扇形的面积的函数,把代码从这样压缩成了这样,告别代码复读机。 但这个函数还存在一个问题,在原来的程序里面,我们的 sector area、 sector area 二、 sector area 三都被依次复制成了第一、二、三个扇形的面积。在我们后续需要再使用这些计算结果的时候,可以随时拿来用。 但在我们新版的程序里,我们并没有任何变量来储存这些计算结果,无法进行后续使用。你可能有疑惑,这个 sector area 不是被复制成了计算结果吗?那这里就需要了解一下 多用玉的概念。我们在函数里面定义的变量都只是局部变量,出到函数外面就访问不到了。 比如在函数里面定义贝拉 a 的值为三,那么在这个函数里面我们可以顺利获取到 a 的值。但在这个函数之外,不管是运行这个函数前还是运行函数后,拍档都会说 a 不存在。 因为 a 在这个函数里被定义只是局部变量,只作用于函数里面。因此通过调用函数来运行某端代码和直接运行某端代码并不是完全一样的。 从这一角度看,函数虽然可以让我们不当复读机,但获取不到里面变量的值,是不是还是有点鸡肋?那当然不是,瑞唐语句的作用就在 此诗体现出来了。 return 写在函数的最后一行后面跟上我们想要他返回的东西,那么函数在执行时不仅会逐行运行里面的语句,还会在函数完成调用后返回那个东西。 这个返回值不管是用来给变量复值,还是被打印出来还是其他,都无所谓。最重要的是,他给了我们在函数之外继续用那个值的机会。事实上,在你没写瑞特语句的时候,拍到函数的返回值会默认为囊,即返回空值。 如果你把某个变量复制为没有 return 语句,函数的执行结果就会发现变量值为 no。 比如 print, append 等,实质上都是返回值为 no 的函数,所以我们一般直接调用不进 进行变量复制。而 land, some 这些都是带返回值的函数,所以我们一般会把它们的调用结果复制给其他变量, 回到我们计算扇形面积的函数,这个函数只会打印出扇形面积,但并没有返回给我们扇形的面积。还以做包子的机器为例, 这就好比在你给了他面粉和肉馅后,他做是做了,但做完后只吼了句做出来的包子是什么样子,但并没有返回给我们。 但再加上这句 return 后就不一样了,我们就可以把某个变量复制为这个返回值。现在这些变量就储存着不同扇形的面积,可以拿去进行更多后续操作了。下面是实践时间,我们之前写过一个变卖 计算公式,身体质量指数等于体重除以身高的平方。那我们这次的目标就是用函数把这个计算器再写一遍,他需要满足以下作用,第一,可以计算出任意体重和身高的变卖值。 第二,在函数的执行过程中,打印出一句话,您的变卖分类为冒号,后面跟上类名,比如偏瘦,正常、肥胖等。第三,返回计算出的变卖值,你可以先把视频暂停,根据这些信息试着自己写一下, 那我要开始了,要毕业函数的话, def 后面跟上函数名,括号冒号这个函数,因为可以 计算出任意体重和身高的变卖值,那么体重和身高都需要作为参数放进来。变卖的计算公式非常的简单,直接体重除以身高的平方。 接下来我们要对变卖分类进行判断,如果变卖小于等于十八点五,分类为偏瘦。 大于十八点五,但小于等于二十五,分类为正常。 这里我们可以把条件简单写为 bm 小于等于二十五, 因为小于等于十八点五的情况已经囊括在第一个分支里了,那进入第二个分支时,说明变卖必然已经大于十八点五了,那下一个同理, l live b m i 小于等于三十,分类为。 最后,如果大于三十为肥胖,可以直接用 s 去概括。 打印的内容是您的变卖分类为,这里可以用到 f 转发括号里面跟上变量名。 最重要的是,我们还要返回这个计算结果, return bmi。 现在这个函数就已经写好了,我们可以测试一下调用函数,比如一点八七十, 可以看到打印出来了, b m i 分类。如果我们要看 b m i 的计算结果,就可以搞一个变量复制为函数的返回值,打印它 出来看一看。现在可以看到计算结果也被成功打印出来了。我们下个视频见 程序圆圈有一句流行的话叫不要重复造轮子,意思是既然已经证实了圆形的轮子好用,直接拿来用就得了,不要再自己去捣鼓其他形状的轮子了。 这句话要在上学的时候说,就不管用,你不能跟老师说开,代表已经把满分的作业做出来了,我拿来抄就得了,不要重复造轮子嘛。但写代码的时候,把别人写好的代码直接拿过来用,是非常正常并且高效的行为。 比如,如果你要对列表里面的所有数字求和,你可以自个写个函数,然后每次需要求和时就调用这个 函数。但拍档已经给你提供了一个叫 some 的内置函数,直接调用就可以得到列表里所有数字的和,就没必要自己定义。你可以在拍档官方文档里查看所有的内置函数,里面包括了我们已经熟悉的 print land。 但由于内置函数数量毕竟比较有限,很多情况下不够解决我们的问题。比如里面就没有一个可以帮助我们找中位数的函数, 这时候我们可以把目光投向拍档标准库里的其他模块,模块就是一个拍档程序, 引入模块后,里面的函数和变量都可以为你所用。比如你想计算一串数字的中位数,你可以自己写一个函数出来,先对列表进行排序,然后通过锁引取出中间那个数字,这里面连在一起的 两个除号是除完后再向下取整的意思。但是除了自己定义函数,你也可以引入拍档模块里的函数,比如拍档有个模块叫 statistics, 帮助进行统计相关的计算里面就有个叫做 million 的用于计算中位数的函数, 那么这一坨代码就可以被简化成两行代码,第一行引入 statistics 模块,第二行使用 statistics 模块里面的 media 函数。 有人会疑惑,为什么 some 是内置函数,而这个 medium 不是内置函数,必须要引入后才能使用, 原因是内置函数都是很常用的函数,而 media 并没有那么常用。这就像常用的家具,比如电视,可以直接摆家里不那么常用的家具,比如烧烤炉,可以平时放 仓库里,需要的时候再搬出来用。引入模块的方式有三种,第一种是 employ 的语句,也是前面示范过的那个用法,在 employ 的后面跟上模块的名字,比如 employed statistics 之后要用模块里的,比如函数或变量的时候,就用模块名点函数名或模块名点变量名来使用。 第二种是用 from employ 语句, from 后面跟上模块的名字, employ 的后面跟上你在那个模块里要使用的函数或变量,多个的话用逗号进行分格。 这样的好处是你每次要用到那些函数或变量的时候,不需要再带上模块的名字。第三种是用 from input 信号语句,放后面跟上模块的名字, 这样做会把模块里面所有内容都进行引入,你在使用时全都不需要在前面跟上模块名了。虽然这样做在你需要用到同一模块里多个内容时很方便,但仍不推荐使用。 原因是用新号的时候,模块里所有函数或变量都会被引入,很可能包括很多你用不到的。 那假如你引入了模块 a 和模块 b, 他们里面都有一个名为 a、 b、 c 的函数,这就会产生命名冲突。在对应 a、 b、 c 的时候,你可能会懵逼,这到底是模块 a 里的 a、 b、 c 函数,还是模块 b 里的 a、 b、 c 函数? 但如果使用第一种 import 的方法,通过前面的模块名,你就很清楚是哪个模块。如果用第二种 import 的方法,假如你要用的是模块儿 b 里的 a、 b、 c 函数,也 可以选择性的直引入模块 b 里的 a、 b、 c 函数。在拍档的官方文档里,可以看到拍档标准库里所有的内置模块,这些你都可以 import, 包括处理字符串的、处理日期和时间的、处理文件的正则表达是相关的、数学相关的等等。 点击模块就可以看到里面包含的函数和变量的介绍。如果你好奇引入的函数具体是怎么写的,可以查看别人写的原代码在拍唱。如果是 windows 系统,按住 control 键点击函数名。如果是 mac os 系统,就按住 command 键点击函数名。 但还有些时候,连拍到标准库里的这些模块都不够我们使用了。我们除了可以引入官方提供的模块之外,还可以引入第三方库的模块。 第三方库的意思就是不是拍档官方提供的,而是其他程序员提供的,所以数量更加庞大和多样。引入第三方模块的语法和前面的一毛一样,但不同的是,在引入之前,你需要先安装,也就是从互联网下载别人写好的模块。 打个比方,安装就像是把某个家具从家具店拖到自家仓库,而引入就像是把某个家具从自家仓库拿出来使用。 所有拍档标准库里的模块都已经在仓库里了,所以只需要用 input 语法引入,而第三方库都只在互联网上,所以还需要先安装,使用的时候再用 input 语法引入。 拍 p i 点 or 这个网站可以对第三方库进行搜索,比如有个财经数据接 口库叫 a k share, 就可以在这里搜索到,还可以查看介绍和用法。要安装的话,去到终端输入 pip insto, 后面跟上库的名字,比如 pip instal a k share。 安装成功后就可以用 import 引入进来,再引入后就可以使用这个模块里面的函数了。比如可以用这个 get c f f e x daily 函数获取二零二二年二月二十二号的中国金融期货交易所交易数据。 拍档有很多好玩的第三方库,可以多探索探索,我们下个视频见。 新手在学习编程的路上,一个躲不过的 car 就是面向对象编程,也叫 o o p。 他当然不是你让你对象坐你对面写代码,就 算面向对象编程了,但要完全理解他,难度不见得比找一对象低。温馨提示,本视频目的是帮你理解 op 概念,不涉及讲解,具体的 op 代码请用拍档做简单示范。语法讲解请听下回分解。 面向对象一般会和面向过程对比。接触对象之前,我们基本上都是在面向过程编程。 过程是负责完成某个具体任务的代码,基本可以理解为函数。面向过程编程的核心就是把要实现的事情拆分成一个个步骤依次完成。 比如我们写个 atm 的程序,要往里面依次存入五十块和取出一百块,那就按照顺序写出这些步骤,并配合定义出存钱和取钱的函数。假如我们还需要记录存 钱和取钱是哪个 atm 机执行的、 atm 属于哪个银行以及纸币的编号,那就可以把这些作为参数补充上去。 这种写法没什么毛病,但如果还要记录更多性质,比如 atm 所属支行、纸币发行年份等,这些散落的数据,一方面会增加函数参数的数量, 另一方面, atm 有编号,纸币也有编号,这些数据在传餐过程中混在一起,并不利于我们理解其具体含义。随着程序长度和逻辑复杂度的增加,代码的清晰度可能由此降低。但如果我们用面向对象编程呢? 正如名字所言,相比过程,他以对象为核心,变相对象编程,首先并不会聚焦于第一步是去存钱还是取钱,而是模拟 真实事件,先考虑各个对象有什么性质,能做什么事情。比如每个 atm 都有自己的性质,包括编号、银行、支行,那么我们可以提取出这些性质,定义 atm 类,然后用类创建对象。 类和对象之间的关系是,类是创建对象的模板,对象是类的实力。更通俗点说,可以把类想象成制造具体对象的图纸, 图纸上说 atm 可以有编号、银行支行这三个属性,那么通过 atm 类创建出来的 atm 实力, 无论是招商银行南苑支行编号零零一的 atm, 还是中国银行北苑支行编号零零二位的 atm 都是 atm 对象。这些编号银行支行则是不同 atm 对象各自的属性。我们可 用相同的方式把纸币类以及通过纸币类创建的两个纸币对象也定义出来。现在这些对象就可以直接作为参数传入存钱和取钱函数中。 你可能会说且慢,虽然现在参数是少了,但多了两大坨定义类的代码,这不是得不偿失吗?面向对象除了能让参数更少之外,用对象把相关属性绑定在一起,还有利于让程序逻辑更加清晰。 比如,虽然 atm 和纸币都有编号,但我们用 atm 一点编号获取属于 atm 一的编号, 用纸币一点编号获取纸币一的编号,这能让人更加清楚性质所属的对象是什么,以及假如我们存取钱的时候还有打印记录,如果不用对象,那得把那一大堆 信息参数传递过去。但有了对象后,就可以直接通过对象来获取。与他绑定的属性相比,带着一大堆数据到处传,这会让逻辑以及数据的后续流动更加清晰。 除了属性之外,另一个能和对象绑定的是方法。正如真实世界里,对象拥有不同的属性,并且能做不同的事情,那属性就对应对象拥有的性质。而方法对应对象能做些什么? 还是以我们熟悉的面向过程编程先作为例子。如果要执行洗衣服的任务,我们就按顺序写出这些步骤,并配合定义出放、开机、清洗、烘干等函数。 可以看到,面向过程编程就像说明书一样,一步步指导执行各个步骤。而面向对向编程呢?在这里面, 人、洗衣机都是执行事物的对象,人能放东西和开机,洗衣机能清洗和烘干,所以这些可以作为类的方法被定义出来。换个角度来看,所谓方法就是放在类里面的函数,所谓属性就是放在类里面的变量。 定义好类之后,就可以通过类来创建对象,然后让各个对象去执行这些方法。相比面向过程编程直接聚焦于按步骤执行。面向对象编程,把事物先分解到对象身上,描述各个对象的作用,然后才是他们之间的交互。 就正如知乎上有个答案说面相过程是边缘体,面相对象是计算题,而且对象不仅可以把所有相关属性和方法绑在一起,结合方法和属性,还能够更优雅的处理复杂逻辑。 比如,如果洗衣机的方法需要用到容量这个信息,那容量其实可以作为属性,在对象被创建的时候就进行设置,后面不管是哪个方法需要用到容量这个信息都不需要作为参数再被传入,而是作为自身属性,可以直接备货渠道。 通过这些例子,我们应该多少能感受到,在逻辑或信息复杂的时候,面向对象编程可以让逻辑更清晰,信息更集中。 除了这些好处之外,面相对象还有三个被反复提及的特性,封装、继承、多肽这三个词吧,虽然字都认得,组合起来啥意思,却并不直观,但没关系,我们一个个看 方装表示写类的人将内部实现细节隐藏起来。使用类的人只通过外部接口访问和实 用接口,可以被大致理解为提供使用的方法。比如如果有人已经写好了洗衣机这个类,你其实只需要知道他有什么方法,方法有什么作用,具体怎么用就足够了。不需要知道方法里面具体是怎么写的, 这和真实世界是一样的。我们现实中使用洗衣机时,也是直接通过操作界面的按钮来使用,不需要知道里面的原理,也不需要钻到洗衣机背后研究。电路板封装能减少我们对不必要细节的精力投入。 继承是在说面相对象编程允许创建有层次的类,就像现实中的儿子继承爸爸,爸爸继承爷爷类。也可以有子类和父类来表示从属关系。比如小学生、大学生都是学生,都应该有学号,年级的属性都要去 去学校。可以看到这两个类之间的共同之处,导致有很多重复代码产生。那我们可以创建出一个叫学生的副类,然后让小学生和大学生去继承这个类。 这样做的好处是,副类的那些属性方法都可以被继承,不需要反复定义。减少代码的荣誉 多肽指的是同样的接口,因为对象具体类的不同而有不同表现。比如虽然小学生和大学生都要写作业,但内容的难度肯定不一样, 所以这个写作业的方法就不能直接定义在副类里面,而是要分别定义在子类里,否则大学生和小学生用的就是同一个方法。那假如作为俩孩子的家长,家里正好一个大学生,一个小学生,你要这俩对象写作业的时候,其实不用 不用管具体写的是高难度还是低难度作业,都可以一视同仁调用写作业方法,而他们会由于所属类不同,执行不同的写作业方法,这就是多肽。 可以想象一下,如果不用类的话,还得用 if 先去判断崽子的类型,然后手动调用不同的写作业函数。面向对象编程的多态让你可以无需判断,统一调用同一名称的方法。 但这也不是说面向对象就一定优于面向过程,如果他全方位碾压面向过程,那面向过程也不会成为另一个主流了。 只能说选择哪个还是取决于具体场景具体需求。当然了,如果你用的是 say 这种纯面相过程语言或 java 这种纯面相对象语言,那咱也不需要花时间纠结了。那现在你 应该对面相对象这个不是那么容易理解的概念有了更深的认知。如果还不理解,那就收藏一波,回头多看几遍就理解了,我们下个视频见,拜拜。 通过前面的八分钟搞懂面向对象编程这个视频,你应该对类和对象都有了大致的了解。 类是创建对象的模板,对象是类的实力,类定义了对象有何种属性和方法,而对象拥有的具体属性则可以不尽相同。那这个视频里,我们要深入面向对象编程的具体语法,创建一个自己的类, 先是关键词 class 空格,后面跟上类的名字和定义普通变量时的下滑线命名法不同,他 i don't 在定义类名的时候用的是 pascal 命名风格,特点是用首字母大写来分隔单词, 然后类名后面要跟上一个冒号,表示下方是第一类的代码。作为例子,我们可以定义一个可爱猫猫类叫 cute cat, 下一步是思考这个类的对象都拥有什么属性。猫猫可以有的属性包括名字、年龄、花色等。 内有一个特殊的方法叫做构造函数,主要作用是定义实力对象的属性,他必须要被命名为 innate, 前后得有两个下划线,注意是俩 括号里面可以放任意数量的参数,但第一个参数永远是被占用的,得用于表示 对象自身约定,俗称叫 self, 他能帮你把属性的值绑定在实力对象上。 比如猫猫的名字属性为 lampton, 可以写 self, 点 name 等于 lampton, 说明是对象的 name。 属性的值如果写成 name 等于 lampton, 前面没有 self, 拍档会觉得只是在给普通的 name 变量负值,就不会把这个值看成是对象的属性。 现在我们就可以创建个猫猫对象了。在拍档创建对象是用类名括号里面放入参数,这样以内的方法就会被调用并返回一个对象。 你可能会说,嗯,等一下,但以内的方法还需要 self 参数呢?传哪去了?这个 self 是不需要我们手动传入的,记住 这点就可以了。调用 cute cat 创建对象时,以内的方法会自动运行,对象的 name 属性被复制为 lampton, 一个名字为 lampton 的猫猫对象就被创建完成了。 要获取对象的属性,可以用对象点属性名来获取,比如 cat 一点 name 会返回这个 cat 一对象所绑定的 name 属性的值。 we lampton 当然了,并不是所有猫猫的名字都叫 lamton, 所以应该给 innate 更加灵活的属性负值。比如从参数获取 name 的值, 那创建对象时就需要在括号里面传入一个猫猫的名字,然后以内的方法会执行。 name 属性的值被绑定为传入的 name cat 参数的值, 那获取到的这个猫猫对象的名字就会是我们传入的那个参数的值了。 我们还可以给猫猫添加更多属性,比如年龄,花色。在创建对象时传入对应参数即可,那么对象的属性值都会被绑定为我们通过参数所传入的值。 你已经掌握了定义属性和创建对象在面向对象编程上迈出了很大的一步。但类除了可以定义属性,即对象有什么性质之外,还可以定义方法,即对象能做什么事情,预知后事如何,请听下回分解。 上个视频里,我们创建了一个可爱 猫猫类,并且定义了该类的对象可以拥有名字、年龄,花色、属性。复习一下,通过 class 关键字可以创建一个类,通过音类的这个构造方法,可以定义对象拥有哪些属性。 通过 class 名字后面加括号,可以调用 in need 来创建新对象,并且把对应属性进行复制。但我们还留了一个坑,没有填,就是定义对象拥有的方法, 方法表示对象能做什么事情,比如可爱猫猫,对象可以思考,可以叫唤。定义方法很简单,和我们创建普通的函数差不多,只有两个区别, 第一是要写在 class 里面,前面要有缩进来表示,这是属于该类的方法。第二是和 init 一样,第一个参数被占用,用于 表示对象自身约定,俗称为 self。 对于 in it, 我们说 self 可以让我们把属性值绑定到对象自身上,那方法为什么也需要这个 self 呢?一个作用是可以让我们在方法里面去获取或修改和对象绑定的属性。 比如如果小猫叫唤的次数和年龄成正比的话,就可以这样写,字符串乘以数字表示,把字符串重复那么多次,喵乘以对象的年龄属性,结果就是如果小猫一岁会打印出喵,小猫三岁会打印出喵喵喵。 这样就实现了方法调用,结果根据属性的不同而改变。要调用类方法,就用对象点方法名括号里面放上参数进行调用。 和构造方法一样,我们不需要手动把 self 传入方法,自然也可以接受更多参数,比如小猫还可以思考,那思考的内容就可以作为参数传入,盗用时把参数值放进括号里面就好。下面是实践时间, 我们的目标是定义一个学生类属性,要求包含学生姓名、学号以及语数英三科成绩,而且要能够设置成绩并打印出该学生所有成绩。你可以先暂停。想一下像这样一个类大致要怎么写。 首先创建类的话,关键词 class 后面跟上类名 student, 然后去定义盈利方法。注意是两个下划线, 可以看到这个编辑器已经自动给我们加上了第一个 self 参数,然后因为每个学生的姓名学号肯定都不一样,所以我们可以用参数去获取, 然后绑定到学生身上。 这里虽然都是 name, 但 self 点 name 说明是绑定到对象身上的属性,而这个 name 就是普通的变量,它的值是通过参数传进来的。接下来一样的操作,定义学生的学号。 那语数英三科的成绩呢?我们可以定义一个字典,让每个学生的每科成 成绩最开始的初始值都是零。 如果每个对象都拥有一样的初始之那其实我们就不需要从参数去获取,可以直接去进行定义。 现在呢,可以创建两个学生对象试一下,比如创建小陈, 随便给一个学号 再创建一个小增。 那么现在如果我们用这个对象名点 属性名,就可以获取他们各自的属性值, 运行一下看一下, 可以看到他们各自的这个 name 属性和这个 grace 属性都被打印出来了。 接下来呢,我们要定义设置成绩的方法,来改变这些初始值为零的成绩, 还是 def 关键字跟上方法的名字括号 里面第一个参数还是默认为笑。然后因为我们要改变科目的成绩,所以要先知道改哪个科目以及改成什么样的成绩,这些都可以作为参数去穿入。 那这里呢,还有一个额外的逻辑,就是如果这个科目存在,我们才改,不存在就不管他,所以要先判断这个科目呢是否存在。 如果这门课是 self 点 grades 这个字典里面的键,那么我们就把它对应的值 更新成传入的参数 grape。 那现在这个方法就写好了, 我们可以试一下把小曾的数学成绩改成九十五, 数学九十五,现在打一下,看一下, 可以看到数学所对应的成绩就不再是零了。接下来写打印该学生所有科目成绩的方法, 还是 def 关键字,给它命名为打印所有成绩。 这个方法就不需要任何参数了,因为学生的成绩我们是可以直接从他的 self degree 去获取到的。那为了更加清晰呢,我们其实可以先打印一下这个学生的相 关信息,比如说把他的名字打印出来,然后他的学号, 然后要打印出所有成绩呢,我们可以用一个 four 循环,那么这个 four 循环呢?可以这么写,就是针对 soften grades 这个字典,我们去循环它每一个 hose 这个键, 然后打印出对应的科目 及这个科目的成绩,我们还是从这个字典里面通过 cos 这个键去取他的分数作为值。 那现在这个方法也写好了,这个 course 呢就是对应了,比如说语文、数学、英语,然后这一块呢,其实就是对应了后面的数字, 那现在我们可以试一下,把比如说小陈的语文成绩给他改一下, 然后把他的数学成绩也改一下。 现在我们就要用这个 print grade 去把它的所有成绩都打印出来, 可以看到就是设置好的新的成绩全部都被展示出来了,我们下个视频见。 在面向对象的世界里,如果把人类和小猫都出现成类的话,可以写成这样,人类有名字,性别,有两只眼睛,没有尾巴,这些都是属性,然后人类可以呼吸啊屎阅读, 小猫也有名字、性别,两只眼睛有尾巴,然后小猫也可以呼吸拉屎。虽然不能阅读,但是可以在你阅读的时候抓你 发。每当我们发现自己写了一些复读机代码的时候,脑海里就要回想起软件开发里重要的卷。原则意思是不要重复你自己。既然我们要追求尽量少的重复代码,那上面这些就应该有办法改写。 面相对象编程有个重要特征叫做继承,意思是可以创建有层次的类,就像现实中的儿子继承爸爸,爸爸继承爷爷。类也可以有子类和父类来表示从属关系, 然后和遗传学上的父子一样。就好比老龙生出来的小龙也会长两根须须,老老鼠生出来的小老鼠也会打洞一样,子类会继承父类的属性和方法。回到前面的类的例子,人类和猫都是哺乳类动物,他们都有两只眼睛,都会呼吸和拉屎, 因此可以去创建一个叫做 memo 哺乳类动物的类,把这些共享的属性和方法全部都挪进去,然后人类和猫都可以继承这个类。具体写法是在类名后面加上括号,里面写上副类的名字。 这个时候这个构造函数以及拉屎和呼吸的两个方法虽然没有在 human 和 cat 类下面,但也被继承了。 现在如果创建一个 ki 的实力,由于子类没有自己的构造函数,就会调用到负类的构造函数,让实力具备名字、性别、眼睛数等属性。 这个实力调用拉屎方法时用的也会是负类的方法。但是如果子类有自己的拉屎的方法的话,就会调用自己的,这背后的逻辑是优先看所属的类有没有该方法,没有的话 网上找副类的同名方法用。不过我们还没有完全达成想要的效果,因为人类和小猫各自的 hasty 属性值不一样,不能只写在副类里。 但如果我们像这样给子类写以内的方法,那创建子类实力时,就会优先调用子类的构造函数,导致实力只有 hastel 属性。一个办法是在子类以内里面把 name、 sex 等属性也全部都写上,但这又会造成重复代码。 更优雅的做法是在此类下面用 super 这个方法, super 会返回当前类的副类, 所以在子类的 in it 方法里面写 super in it, 这就会调用负类的构造函数,那么子类也会有姓名、性别、演技、数量的属性了。所以通过继承,我们成功把重复的属性和方法代 网横给移除了,并且在实力化获得熟悉,但用方法是和之前都一毛一样,没有任何区别。最后给个小技巧,什么时候可以用继承呢?如果说 a 和 b 两个东西,你可以说成 a 是 b, 那么就可以把 a 写成是 b 的字类。 比如说人类是动物,那人类可以写成是动物的子类。新能源车是车,那新能源车可以写成是车的子类,你学会了吗?下面是实践时间。 假如你要给公司写个人力系统,员工分为两类,全职和兼职。所有员工都有姓名和工号属性,并且都有打印信息的方法,可以把这俩属性打印出来。全职和兼职的区别在于,全职员工按月发工资,有月薪属性,而 兼职员工按天发工资,有日薪,还有每月工作多少天的属性,这个区别让他们计算月工资的方法存在差异。现在你可以暂停试着写一下提示,可以用类继承,把全职和兼职共同的属性和方法放到员工这个副类里面。现在我要开始写了。 首先定义一下员工这个负累,然后把姓名、工号这些共通的属性全部都放到构造函数里面。 接下来再定义一个打印信息的方法,把名字和编号给他打印出来。 然后是全职员工这个类, 由于全职员工继承自员工类,所以在类名后面加上括号里面写 employee。 接下来还是构造函数, 姓名和公号的初始化方法已经在副类里面写好了,但是我们还缺个月薪属性,所以这里用 super 表示副类,然后是 inlet, 这样就可以调用副类的构造函数,里面放上姓名和编号, 然后还要把全职员工自己的月薪属性给写上。最后 是我们要计算全职员工的每个月的工资, 这个就很简单了,直接就是员工的月薪。 然后是兼职员工 today, 和前面差不多,也是继承自 employ 这个副类。 构造函数里面还是用 superdale in it 来初始化姓名和编号。全职员工呢,有两个自己的属性,日系以及每个月的工作天数, 所以把它们也写在构造函数里面。 最后是计算坚持员工每个月的工资, 这个呢会比全职要更复杂一点,他呢等于日薪乘以每个月的工作天数,现在累就定义完成了。我们可以用两个员工来试一下,创建一个叫张三的全职员工, 给他姓名编号还有月薪的属性。然后再创建一个叫李四的兼职员工, 还要给他姓名编号,还有他的日性以及月工作天数属性。 我们打印一下他们两个的信息,运行一下,可以看到这里呢,调用的都是继承自负类的 print info 方法。那如果我们再打印一下他们每个月拿到手的工资, 再运行一下,此时调用的呢,就是他们各自的计算每个月工资的方法。我们下个视频见。 在编程时对文件的操作,包括对文件的读写是非常常见的文档、图片、音乐等,虽然内容形式不同,但本质上都是 属于文件,而文件会归属于某一个目录下面你可以把目录看作是文件夹。假如我们想对某个文本进行修改,会直接去存放那个文本的目录,点开文本进行编辑。如果我们想用代码对那个文本进行操作的话,问题来了, 代码怎么知道如何找到那个文件嘞?要解决这个问题,需要先了解一波电脑操作系统的目录结构。 一般 linux、 macos 等类 unix 操作系统目录结构会像树根一样,这个根节点叫根目录,一般用斜杠表示,一切的文件目录都存放在根目录下面。 windows 系统就不一样了,它每个磁盘分区都有自己的根目录,用分区名加反斜杠表示。 虽然这两种目录结构长得不一样,但地位、文件的位置都可以用两种方法,绝对路径和相对路径。绝对路径是从根目录出发的路径。由于以根目录为基准,对于 linux、 麦勾 s 等类 unix 系统,绝对路径就是以斜杠开头, 路径中的每个目录之间用斜杠进行分隔,最后以目标文件或目标目录结尾。对于 windows 系统,绝对路径以分区名加反斜杠开头,路径中的每个目录之间用反斜杠进行分隔,同样最后以目标文件或目标目录结尾。 相对路径则是从一个参考位置出发,也就是说他表示从那个位置来看其他文件处于什么路径。用相对路径时,我们用点来 表示参照文件当前所在的目录,用点点表示更上一层的负目录,如果继续往上走,就用点点跟上斜杠或反斜杠进行分隔,这取决于操作系统后面再跟上点点表示当前文件所属目录的负目录的负目录。 如果是往更下层走的话,同样以斜杠或反斜杠来分隔路径中的目录,所以可以看出来相对路径都是以点或者点点开头的, 另外,点斜杠是可以省略的。所以在同一目录下的文件,想互相用相对路径找到彼此的话,可以直接使用文件名。 很多编辑器都能帮你复制文件的路径,比如在 picture 右键点击文件,选择复制路径引用,你就可以获得那个文件的绝对 路径,以及以最顶层项目目录为参考的相对路径。能用绝对路径或相对路径来定位文件的位置后,我们就可以对文件进行操作了。具体能如何操作,我们下个视频见。 如果你需要一个程序来帮忙计算销售数据,一种方法是根据数据文件,把数据一条条复制到代码里面,然后通过执行代码来获得结果。 如果有多份不同日期的市场数据,就要反复修改程序里的变量,似乎有点麻烦。 但如果你学会了文件操作,就可以让同一段代码读取不同的市场数据。文件只需要对文件名进行改动即可,比前一种方法优雅很多。用拍档读文件的第一步操作得是 是先打开目标文件。我们用 open 函数里面先放上文件的路径,可以是相对路径,也可以是绝对路径。不熟悉路径的同学请复习上一个视频。 第二个参数是模式,模式是一个字符串,常见的模式包括 r 表示读取模式, w 表示写入模式。由于这个视频先讲读文件,所以模式我们写 r。 另外这个参数也可以不写,不写时默认为读取模式。 在读取模式下,程序找不到你传入的文件名的话,就会报一个叫 fire not fire 的错误提示文件不存在。 open 函数还有个可选参数叫 incoling, 表示编码方式。现在文件一般的编码方式都是 u t f 八,所以这个参数传入 u t f 杠八的值,就会用这个编码来读取文件。 如果你想要了解更多,可以看我之前做的关于编码的科普视频。如果 open 函数执行成功,会返回一个文件对象,我们可以后续对他进行读取或写入操作。 针对读文件来说,文件对象有个 read 方法,我们调用后,他就会一次性读取文件里面所有内容,并以字符串形式进行返回。 一般我们用代码操作的文件格式都会是这种很简单直接的,以文本格式为例,代码喜欢 txt 这种纯文本,可以直接把里面的内容转换为字符串,而不是 word 这种还有字号、字体、颜色等花里胡哨的格式,这就很有可能读出问题。 另外还需要注意的是,如果调用完 read 后再次调用,你会发现返回的结果为空, 因为程序其实会记录那个文件读到哪个位置了。第一次 read 的时候已经读到结尾,第二次 read 后面没有内容了,所以会返回空字不串。 另外,在文件特别大的情况下,最好不要用 read, 因为读出来的内容会占用很大的内存,甚至把内存给爆了。如果你不想一次性读完整个文件,可以给 read 传一个数字,表示读多少字节。下一次调用 read 的时候就会从那个位置继续往下读。 除了用 read, 我们也可以使用 read 方法来读文件,这个文件只会读取一行的内容,下一次调用就读下一行,他会根据换行符来判断什么时候算本行结尾,而且换行符也会被当成读到的内容的一部分。你可能会问,那假如文件有无数行, 我怎么知道 redline 要对应多少次才能读到结尾呢?如果读到结尾, redline 方法会和 red 一样,返回空字符串,表示后面没有内容了。所以我们一般会用 while 循环判断,只要返回的不是空字符串,就继续读下一行,否则就退出循环。 如果你觉得啥玩意怎么一行一行都这么费劲,那还有一个方法是 read。 lines 比之前那个名字多了一个 s realize, 会读取全部文件内容,并返回由每行组成的字符串列表,所以它一般会和 for 循环结合使用。先调 realize, 把所有行读出来,然后一行一行循环列表里面的所有内容。 现在我们已经掌握了三种读文件的方法,可以根据具体情境和需求选择最适合的方法。 文件后我们还要做一件事情是关闭文件。文件对象有一个叫 close 的方法,名字正好和开头的 open 函数是反义词,调用后该文件对象就会释放系统资源,所以每次完成文件读写操作后都应该关闭文件。 但有些时候我们可能忘记调用 close。 那另外一种方法是用 with 关键字, with 后面跟上 open 函数的调用,然后 as 后面跟上文件对象的命名冒号。 缩进的代码块里放上对该文件对象的操作,这样在缩进的内容执行完毕后,文件就会被自动关闭。 这种写法能让代码更加简洁,我们也不需要再单独调用 close 方法了。下面是实践时间,既然要练习读文件,就先创建个用来读的文 像前面说的代码适合读纯文本。创建纯文本可以用 windows 系统自带的计时本或麦格外自带的文本编辑。但更简单的方法呢,是在代码编辑器里面右键新建文件,输入文件名。 这里的后缀可以用点 txt 表示这是个纯文本,然后写几行内容。我这里呢,就随便复制一首诗,注意文件所在的位置啊。决定了读文件时咱们需要输入的路径,这个文件呢,当前就创现在我的这个项目文件夹的下面, 然后回到咱们的拍档程序。读文件前呢,要先打开文件,所以用 open 函数,这个函数呢是拍档时代的,所以不需要 import。 然 然后第一个参数呢是文件路径,为了简洁呢,咱们可以使用相对路径,相对路径就是相对于当前我正在编辑的这个代码文件而言,我们要读的文件和他处于什么位置? 因为这个要读的文件和代码文件都处于同一文件夹下,所以相对路径就比较简单了,他就是点表示当前文件夹, 然后是分割符,注意如果是内音系统的话呢,分割符就是斜杠, window 系统用的是反斜杠,然后分割符后面跟上文件名,这就表示这个要读的文件和代码文件是处于同一个文件夹下面的。 然后第二个参数呢是模式,由于我们是读文件,所以模式为 r, 但这个不写也可以,因为不写 其实就默认为二。然后我们还可以加上 incoding 这个可选参数, open 函数默认的 incoding 是跟随系统的,所以咱们最好要专门写名 incoding 等于 u t f 杠八。 那这个 open 函数呢,就会返回一个文件对象,我就给他命名为 f 吧, f 呢就是 file 的首字母,有了文件对象后呢,我们就可以开始读文件了,最直接的就是用 read 方法, 他呢会把文件所有的内容以字符串进行返回,所以我们这里可以先用一个变量储存一下这个内容,然后打印出来看一看,最后记得还要调用 close 来关闭文件,释放资源,现在就可以运行看一看,结果 可以看到,就这么三行代码呢,就把文件内容全部的打印出来了,和他原本的内容是一致的。那有些时候呢,我们可能会忘记调音 close, 所以呢,也可以改用 with, 这样子的话呢,就不需要专门去 close 了,所以这里就是 with open s f 冒号把 cos 这行删掉,然后这些所有和读文件相关的操作都要记得前面有缩进。 在运行一下,可以看到和刚才的结果是完全相同的。除了 red 之外呢,我们还可以用 red line 来读行读取, 比如说如果我们盗用两次 red light 的话呢,它就会读取文件的前两行的内容。另外需要注意的是呢,对该文件 对象的所有的操作前面都得有缩进,那假如说第二行前面我不给缩进,他不在这个位置下面的话呢,那运行到这行的时候,文件对象其实已经被自动的关闭了, 所以呢,他就会产生一个报错,那我们把缩进给他恢复正确,再运行一下。另外你可能有一点会疑惑的是,为什么用 red lie 这里会有额外的空行,原因呢是因为 red lie 呢,会把每行后面的这个换行符也给读到, 同时呢, print 它本身就会默认结尾换行,所以两个换行符结合起来就会形成了多一个的空行。那我们学习的第三个读取的方法呢是 read lice, 直接打印出来看看,可以看到呢,它会 返回一个列表,列表里面的每一个元素呢,就是每一行的内容。这里咱们就可以直接的看到每行结尾的换行符呢,也都被读进去了,作为了文件的一部分, 那一般 red lights 呢,会结合复语循环使用,我们可以先把读到的内容给它复制成一个变量,然后就对这个列表去进行一个循环, 可以用它打印出每行的内容,可以看到这个效果呢,也是把文件的所有的内容都给打印了出来,我们下个视频见。 假如你是一位老师,想根据熊孩子们每次考试的分数计算出综合平均分,上 上回是说到如何读文件,所以如果分数是记录在文件里的,你已经知道该如何读取了,但计算后的结果如果只是记录在程序变量里,每次想看结果的时候都要运行下程序吗?这不太优雅。 除了读文件,写也是常见的文件操作,把程序输出结果储存为文件就可以不用反复运行程序,也可以把结果轻松共享给他人。 写文件和读文件有非常多的相似之处,我们都需要打开文件,并且在操作完成后关闭文件,所以还是可以用熟悉的 with open s。 第一个参数里放文件路径,而第二个参数我们要传入模式,写入模式用 w 字符串表示,所以我们传入 w 在读文件模式下,即第二个参数传入二 的话,如果根据这个文件路径找不到文件,程序就会报错。在写文件模式下就不存在这个问题,如果文件不存在,程序就会自动创建传入文件名的那个文件。 接下来我们还是可以传入可选参数 incoding 来确保写入的文件编码也是 u t f 八。另外需要注意的是,用 w 模式打开文件进行写入的话,如果那个文件已经存在,就会把原本的文件内容清空,所以用 w 模式前要三思而后行, 三四后,我们就可以对文件进行写操作了。 s 后面你选择的变量名就对应着 open 函数返回的文件对象的名字。那针对写文件来说,文件对象有个 right 方法,比如像这样 data 点 txt, 文件里就会出现一句 hello, 如果再调用一次 right 传入 you, 文件里面会变成啥呢?会变成这样没错, right 不会每次调用时默认帮你换行,所以如果想有换行效果的话,你需要自己手动加换行符。 你现在可能会想,如果我不想把原本文件内容清空,只想在后面追加内容怎么办?那就不能传入 w 作为模式参数了,而是应该用 a 表示附加内容,而不是清空重写。 所以说,如果针对原本就有两行文字的文件,用 a 作为模式参数打开,并且接着调用两次 right, 文件就会被附加上 hello 和 you, 而不是只有 hello 和 you。 另外, a 和 w 模式一样,如果传入文件名不存在,会直接帮你创建一个。还有个需要注意的点是,无论是 w 还是 a 模式,你都没 去读取文件里原本的内容。如果硬要对文件对象电用 read 程序会报错,不支持读操作。那咋办呢?难道我们要先 open 一次,用 r 模式去读,再 open 一次用 w 模式去写吗?自然不应该这么麻烦, 在二维模式后面再加一个加号,也就是传入二加,就可以同时支持读写文件。打开文件后,调用 read 和 red 都不会报错了,而且 red 调用后会以追加的形式在文件后面添加新的内容。下面是实践时间, 本次练习有两个小任务,你可以先暂停自己试试。那我要开始了。第一个呢,是在一个叫破 m 表 t x 系列文件里写入这三句词,那遇到文件操作的时候,可以先想一下 应该用什么模式,这里是把内容写入一个全新的文件里,所以可以用 w 模式。在 w 模式下呢,即使文件不存在,程序也会帮我们创建它, 但还是熟悉的 vs open 括号里面呢,要宣传文件路径,我呢准备把它创建在和代码文件同一个文件夹下,所以用相对路径呢,就是点斜杠,开头后面跟上名字, 如果是同一个文件夹下呢,这个点斜杠都是可以省略的。然后模式的话呢,传入 w, 接下来最好还是打印 cody 也给它传入一下,确保编码是 utf 八,那 s 后面呢,可以跟任意合理的变量名,我习惯用 f。 接下来呢,就可以写入这三句词了,那这里呢,其实比较的随意了,我可以调用呃三次 run 方法,比如说像这样, 但这样呢,当前是不对的,因为按照要求每句词后面还要有换行,所以我们还是要手动的加入一下换行符, 现在运行一下看看效果。可以看到呢,这个 pom 点 t x t 呢,就已经被自动创建出来了,然后它的这个格式呢,也是符合我们要求的。那除了这样呢,你还有一种方法是你也可以把所所有的内容都给它拖到一起,这样子的话呢,就是只能调用一次 red, 就好 像这样运行一下,看一下效果也是一样的。第二个练习呢,是在刚才那个文件的结尾再添加两句,这里我们就最好用 a 模式了,因为 w 模式会把咱们之前的给他清空, 所以先把这个 with open as 复制过来,模式改为 a, 然后最后还是调用 right 函数,里面就放上这两句词,还是不要忘记换横幅。 运行前还有一件事情要做,就是就是上面这个,咱们得多加一个换换符,不然这两行就会粘到一起了,好,运行一下,看一下效果, 搞定了。是不是非常的简单粗暴,我们下个视频见。 有些时候我们写的代码有毒,能把程序炸了,也就是让程序产生报错。也有些时候我们写的代码没问题,但因为其他问题,比如用户输入的数据类型不合理等等,也会让程序炸了。 程序在某一行产生报错后,后面所有的代码都不会被运行,这在很多情况下并不是我们想要的,所以我们需要学会如何在程序炸之前走一波预判,捕捉住这个异常,从而能用我们想要的方式去处理错误情况。 在了解如何预判前,我们先了解程序能怎么被炸,或者说有哪些异常类型。用 长度范围之外的锁印,对列表取知时会产生 index error, 即锁印错误。用数字除以零时会产生 zero divisionary, 即除零错误。打开的文件不存在时,会产生 fire not found error, 即找不到文件错误, 让两个字符串做乘法会产生太白而即类型错误等等等等。由于异常类型非常之多,无法全部概括,你写的代码里面问题越多,可能就对不同类型的错误越熟悉。 平时我们应该通过测试等方式,把所有能够避免的 bug 给他揪出来,并且 debug 掉。那如果错误没办法从我们程序员这边避免呢?比如说咱们写过一个计算身体质量指数的程序,让用户输入体重数字,用户就非要给你输一行一行白鹭上, 今天这没法转换成数字,程序就炸了,你甚至连打印一句话去吐槽用户的机会都没有。但是如果能把这个异常给捕捉住,他就不会把程序炸了。我们可以通过 try except 语句去捕捉异常。 try 冒号换行后缩进的代码块里放上你觉得可能会产生报错的代码。接下来在 excel 的后面跟上你想捕捉的错误名字以及冒号。 比如 flow 的函数里面,如果用户传入一个无法转换成数字的字符串,程序就会爆 value every, 所以咱们就可以在 except 后面放 value every 去捕捉它。 在换行后缩进的代码块里面放上那类错误发生后你想相应执行的操作。比如这个例子里面,咱们可以 print 出一句话,告知 用户要输入合理的数字。而且这个例子里面除了可能发生 value error 之外,由于咱们有做除法,如果用户给身高输入个零,还有可能发生 zero division error, 即除零错误, 咱们同样可以把它捕捉住,方式一模一样,在下面跟一个 accept zero division error 缩进大马块里,放上针对那个错误的操作即可。 那有些时候我们可能没办法预判所有可能出现的错误类型。如果你希望无论出现什么类型的错误,程序都不要炸的话,可以直接写个 except 冒号,这个语句会捕捉所有的错误类型。 需要注意的是, try accept 语句在捕捉错误时从上往下运行,如果第一个 accept 语句就捕捉到了对应错误,那后面的 accept 语句 都不会执行了。这个和咱们 if alif 的逻辑很像,只有第一个符合条件的分支会运行。现在你已经学会在错误发生时怎么让程序执行相应操作,而不是直接炸了。但在 except 后面,我们还可以再跟上两个语句, else 和 finally else 冒号缩进的代码块里放上当串里面的语句没有任何错误产生时,要执行的语句。比如用户输入的数据不产生任何问题的话,咱们就可以把 bmi 值的计算结果打印给用户看。 finally 冒号缩进的代码块里放上无论错误发生与否,最终都会被执行的语句。 finally 很厉害的在于,无论是错误被某个 except 语句捕捉,还是没有任何错误产生,还是出现了你没捕捉到的错误把 程序给炸了,凡德里里面的代码最终都会被执行,你学会了吗?那除了利用异常处理语句让程序不炸之外,平时写代码时测试也很重要。要如何确保我们写的代码里面没有毒呢?请听下回分解,我们下个视频见。 在一九四七年的某一天,一位叫格雷斯赫伯的计算机科学家经过了一天的检查,终于发现机器发生故障的原因是有只蛾子钻进继电器里被电死了,导致硬件出现问题。 虫子在英文里是 bug, 所以这个词后来在计算机领域被用来表示程序错误,就像从来没有不犯错的人。对程序员来说,写出 bug 也是相当正常的,但更 关键的在于如何在写出 bug 后能快速直接的发现他并进行改正,而不是等 bug 上线后让用户成为第一个发现 bug 和体验 bug 的人。测试的意义就在于此,他的目的是帮我们确认程序的行为是否和我们预期相同。 而且测试除了能帮我们验证新代码是否正确之外,还能验证在改动老代码之后,不该受影响的地方也仍然会按预期执行,而不是牵一发而动全身。 在写拍档时要怎么测试呢?当当当,下面有请 assert 语句登场。 assert 中文意思是断言它后面可以跟上任何不而表达式,也就是职位处或 force 的表达式。测试时我们会在 assert 后面跟上我们 认为应该为处的表达式。如果 acceler 的后面的表达是最终求职出来的结果为处,那么无事发生,继续运行后面的代码。但如果求职出来为 false, 就会产生 assertion ever 断言错误相当于在提醒运行程序的人。 太太看这里,这不符合预期啊。但用 assert 也有一个问题,就是一旦出现 assertion error, 程序就直接终止了,后面如果有更多的代码也不会运行,我们并不能知道剩下的代码里还有哪些其他问题。 所以一般我们会使用专门做测试的库,他们能一次性跑多个测试用力,并且能更直观的展现哪些测试用力,通过了哪些没有。 unit test 就是一个很常用的 python 单元测试库,单元测试的意 意思是对软件中的最小可测试单元进行验证,比如验证某函数某方面表现是否符合预期。这个 unit test cool 是拍同自带的,我们不需要额外进行安装,但毕竟是个酷,所以我们还是需要用 input 的语句把它引入到测试程序里。 另外,我们一般会把测试代码放到独立文件里,而不是和要测试的功能混在一起,这样能更清晰的划分实现代码和测试代码。 假如我们之前在 my calculator 点拍文件里写了一个做加法的函数叫 my adder, 那可以给他写一些测试用力,比如测试正数加正数和正数加复数的情况。那为了能调用要测试的功能,还要在测试文件里把要测试的函 数或类也引入进来。如果测试文件和被测试文件位于同一文件夹下,咱们引入的语法是 from 文件名 input 函数名或是 from 文件名 input 类名。现在就可以正式写测试了。 创建一个类名字可以以 test 开头表示,这是一个用来测试的类,他要当 unit test 点 test case 的子类,这样就能够使用那些继承字。 unit test 点 test case 的各种测试功能。 在这个类下面可以定义不同的测试用力。每一个测试用力都是类。下面的一个方法,名字必须以 test 下滑线开头,这个命名很关键,因为 you did test 这个库会自动搜索 test 下滑线开头的方法,并且只把 pass 的下划线开头的当成测试用力。那写测试用力之前,先想一下预期的 my add 行为是怎么样的。比如如果传入五和三这两个正数,他应该返回八。如果用 assert, 我们会这样写, 但前面说过,一旦出现 assertion error, 程序就直接中断了。所以我们可以用 unit test 库里 test case 类的 assert equal 方法。咱们的测试类已经继承自那个类,所以可以直接通过 self 调用副类方法 传入的第一个参数和第二个参数,如果相等,显示测试通过,如果不相等,显示测试不通过,但程序也不会炸。想好测试用力后,我们只需要在编辑器的终端输入 python 杠 m。 unit test 表 是运行 unit test 这个库,就会自动搜索所有继承了 unit test 库里 test case 类的子类,运行他们所有以 test 下划线开头的方法,然后展示测试结果, 他会告诉你共运行了几个测试,然后上面的点点不是无语的意思啊,而是每个点都代表一个测试通过, 如果有一个测试没有通过,其中一个点就会变成 f。 unit test 还会详细告诉你是哪个文件下面的哪个方法造成了测试失败以及为什么失败。总之一体化的提供了所有和测试结果有关的信息。 unit test 还有一些进阶玩法,可以帮我们更高效的进行测试,揪出 bug, 具体详情以及课后实践请见下回分解, 我们下个视频见上回书说到 unit test 这个 pattern, 自带测试库,可以帮我们自动找出和运行所有测试用力,一次性展示所有测试结果,并且给出未通过测试的详情, 总之大大提高了我们进行单元测试的效率。 test case lay 除了很常用的 assort equal 之外,还有其他一些可以用来测试的方法,比如 assort true 方法类似于 assort 参数一 is true。 assort in 方法类似于 assort 参数一,应参数二。 这些方法还都有对应的取反方法,比如 assert not equal 方法类似于 assert 参数一不等于参数二, assert false 方法类似于 assert 参数一 is fast 等等。本质上呢, asset to 可以代替所有这些方法,比如这两个测试都是在验证二是否不存在于一二这个列表里,通过与否的结果是一样的。 不过呢,还是推荐用更具针对性的方法,比如想测试元素不在列表里,用 assert not in 这个专门针对元素和列表的方法,而不是 assert to 这个万能方法。原因是在测试未通过的时候,更针对性的方法会给出更详细的失败原因。 有些时候,我们还可以通过额外方法进一步提高测试效率。假如我们要测试一个类,为了能调用各种类方法,我们需要创建实力对象。由于不同测试用力之间是独立的,测试不同方法的时候,我们要不停的创建新对象。 为了减少不必要的重复代码,我们可以利用 test case lay 里的 set up 方法在运行各个测试方法,也就是 test 下划线开头的方法前, set up 方法都会先被运行一次。 这样我们只需要在 set up 方法里面把测试对象创建好,作为当前测试类的一个属性,然后在各个方法里就可以通过属性获取那个已创建好的对象。去写测试语句。下面是实践时间, 假如我们已经写好了一个购物清单类,它包含这些方法,首先是构建方法,他会把 shopping 类似的这个属性复制为传入的字典,字典里面包含商品名和商品对应价格,就像这个例子。然后是 get item count 方法,会返回购物清单里有多少件商品。 get total price 会返回购物清单商品总额。那要给这个类写一个测试程序的话,先新建一个文件 命名,可以以 test 下划线开头,比如叫 test shopping list。 为了能用 unit test cool 帮我们测试写个 input 语句进行引入,然后我们要把被测试的类也给 input 进来,放文件名 input 类名。 现在呢,就可以正式开始写测试了,新建一个类, 让他继承自 unit test 的这个库里面的 test case 的类。那我们呢,可以先测试 get item count 这个方法, 注意方法一定要以 test 下滑线开头,才能被 unit test 自动当成测试用力。 那假如说咱们有这么一个购物清单,他的这个里头呢,有纸巾呃八块钱, 有帽子三十块钱,还有拖鞋十五块钱。那么咱们如果说调用这个 shopping list 的 get item count 方, 他应该返回我们的十三,因为这里头有三件东西,所以呢咱们就可以写 sell 点 set equal, 然后这个 get item count 返回的值就等于三。接下来呢,测试 get total price 方法, 咱们还是可以用刚才的这个购物清单, 那调用这个 get total price 的方法后呢,他反而会给我们的正确的值应该是等于,这是多少?应该是等于五十三, 那咱们还是用这个 soft equal 方法。第二个参数传数字五十三,但这里你可以看到我们其实是在重复的创建这个测试 对象,所以可以考虑使用 set up 方法,注意他的名字应该和我这里的是一模一样的。然后在里面可以创建一个比如说叫 shopping list 的属性,这个名字可以任意取啊, 属性名并不重要。那接下来呢,所有这些用到了我们专门创建的 soft list 的地方呢,我们都可以给他删掉, 他这里呢是有报错,他就说这个 shopping list 变量不存在了,咱们这里是要用这个 self dear shopping list, 也就是它的属性, 那这一处 self 点 shopping list 就相当于是这个 shopping list 的对象了。那现在可以运行一下看看。打开终端,咱们输入测试命令, 就是拍档港 app unit test, 那这里呢,他说运行了两个测试用力,然后测试结果呢是俩点,说明这两个测试用力都通过了。但如果说咱们把这个数字故意改一下,改成个错的, 还是刚才的命令运行一下, 那可以看到的其中一个点,它就变成了 f 表示 failure, 说明有一个测试没有通过,那具体是哪个没有通过呢?他把这个没有通过测试的方法给我们展示了出来, 然后咱们可以看到下面还可以直接跳转到没有测试通过的那一行,他也给咱们写明了没有通过测试的原因呢,是五十三,不等于五十五,也就是说第一个参数他的值是 五十三,然后第二个是五十五,并不相等。所以通过单元测试呢,可以帮我们确定程序行为是否和预期相同。在我们对原先代码进行改动后,也可以通过单元测试帮我们确认不想被影响的地方也还能按照预期执行,我们下个视频见。 假如我们需要计算数字平方后的结果,并用这种格式打印出来,那就可以写这样一个函数,它主要做两件事情,计算,然后打印。比如当我们传入数字三的时候,打印结果就会长这样。 这是一个非常简单的小函数,但如果我们想进行扩展,比如说除了能打印平方的结果,还能打印三次方呢?一个解决办法是,我们可以在传入 数字的同时额外传入几次方,如果是二就计算平方,三就计算三次方。现在问题又来了,如果我们希望他除了能打印平方和三次方的结果,还能打印某数字加时候的结果呢? 是不是觉得无从下手?怎么改逻辑都会看起来很丑?但换个角度来看,我们之所以没能找到优雅直观的改写方法,是因为一直把计算的过程逻辑保留在这个函数里面。但如果说我们把做计算的函数直接作为参数呢? 这样的话,我们先把计算平方三次方加十了函数独立出来。在做计算和打印的函数里,我们可以直接调用传入的函数得到计算结果,继而打印出来。至于传入 这个函数具体在做什么,到底是求平方还是三次方,还是加时候的结果,这个函数里面都不需要管。 而在调用的时候,如果需要计算和打印平方结果,我们就把算平方的函数传入进去。如果需要计算和打印加时候的结果,我们就把计算加时的函数传入进去。 没错,函数是可以被传入函数的,这种把函数作为参数的函数被叫做高阶函数。 需要注意的是,作为参数的函数是直接用函数名进行传入,表示函数其本身,后面不要带括号和参数。 因为呢,一旦有括号,这个函数就被调用了,传入的就是函数的执行结果,而不是函数本身了。那改用高加函数后,整体逻辑 就会长成这样,他可以继续扩展。比如,如果我们还需要计算和打印数字乘五号的结果,就继续定义新的函数,需要的时候传入那个乘五函数作为高阶函数的参数即可。 甚至呢,我们还可以把格式化函数也作为高阶函数的参数进行传入,这样能在保持 calculate and print 函数不变的同时,扩展出不同的打印格式。 总结来看,高尖函数给程序提供了更多灵活性。举个现实中的例子,这就好比某森的多功能美发棒, 他的主机负责产生气流、控制温度和风速这些核心功能,但通过插上不同的配件,比如卷头发的卷筒,或者吹头发的封嘴,这样就能做多样化的功能,用一个主 机达成不同的目的。高尖函数就像是这个主机,而作为参数的函数就像是那些配件。 但还有些时候,我们传给高阶函数的函数并不常用,可能就计算那么一次,还要给他想个名字,专门定义出来,略显正式了。 匿名函数就非常适合用在这种场景下。正如名字所暗示的,匿名函数不需要我们给它起名字,而且像个一次性物品一样,即用即扔。 如果非要拿一个名字只带匿名函数的话,可以叫 lambda, 因为匿名函数的定义是以 lambda 这个关键字开始的。 我们可以直接在调用高阶函数的括号里放上关键词 land, 跟上变量名,然后是冒号。冒号前面的变量名表示的就是传给匿名 函数的参数。而在漫画后面,匿名函数是不需要专门写 return 的,我们直接放上要返回的结果。如果要给匿名函数增加参数,也只需要在 lima 关键字后面把参数用不同的逗号分割开。 你可以把匿名函数当成是没有名字且占用函数更少的函数。比如这样一个匿名函数,如果我们把它定义成普通的函数,会长成这样。 可以看到匿名函数能减少代码行数,不用起名字,不用换行缩进,特别适合只需要一次性调用的场景。 而且除了作为高加函数的参数,匿名函数也可以定义好后被直接调用,盗用方式和普通函数一样,都是括号,然后括号里传入参数。 唯一的区别是,前面的匿名函数也要被扩注,表示这是一个整体。但匿名函数也有自己的局限性,那就是他冒号后面没法有多个语句或表达式,所以只适用于比较简单的场景。 对于多步骤的复杂逻辑,或者是涉及循环地规的,他可能就不够灵活,可能没法用它写出来了。或者即使有些复杂逻辑能用匿名函数写出来,可读性也会很差,别人看不懂。所以这种时候呢,还是老老实实定义普通函数更好。我们下个视频见。 当你看到这个结尾的时候啊,恭喜你已经成功入门拍档超过百分之九十九点九九九九的人了。如果你希望学习拍档进阶或者是其他的编程语言,记得关注我哦,我会持续带来好的知识内容。如果你 下学习拍档数据分析的全流程,包括数据读取、评估、清洗、整理、分析,可实话欢迎加入我的小白玩转拍档数据分析课程,希望拍档编程这项技能能在学业或职场上实际帮助到你。如果这套课程对你有帮助的话,也欢迎分享给周围的人,相信他们都会感谢你的,我们稍后见。