如果图片出不来请去https://www.bilibili.com/read/cv266162,都是本人写的。
标题为什么是‘花心’的else语句呢?这是因为在python里else不仅可以和if搭配,还可以和while,for和上一讲学到的try搭配。
‘花心’的else语句
if和else搭配前面已经有很多例子了,就不再写了,下面就先说一下else和while搭配。如果while或者for语句循环结束,才会进入else里面。如果不是循环结束而是通过break跳出的循环,那么else里的语句就不会被执行。下面是一个求 最大约数的程序:
![](https://i-blog.csdnimg.cn/blog_migrate/9c2ba89e393120ac40b575630783fe24.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7da77d11af2b5e5f887a3bfc60646fda.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7a986a29490c7592ea2629caec7ac82f.png)
我们看到如果for循环完毕,for里面的数是从b//2开始的,因为最小的约数是2嘛(1不算约数好吧),减一直到2,注意,range后一个参数是达不到的,所以是1。如果for循环里的if条件判断一直不满足,也就不能break,我们才能进入else执行打印a是质数的命令。其实这个else语句我时可以用别的语句来替代的,只需要加一个变量n。这里我要插一点,其实如果让我写只判断一个数是不是质数的程序,应该是这样的。
1
![](https://i-blog.csdnimg.cn/blog_migrate/5132749b725fd0ea194af4514281dcc2.png)
里面pow(b.0.5)就是对b开平方。
![](https://i-blog.csdnimg.cn/blog_migrate/ed4a957046e1df4def5cf5d01f104d34.png)
你用b**0.5也行,就是让大家知道pow是什么用法,见到这么函数知道它是干什么的。
我来稍微解释一下我的这个质数的程序,一个正整数分解为两个数相乘,一定有一个数大于等于这个数的开平方,另一个数小于等于这个数的开平方,它们是一一配对的。就根据这个配对关系,我们只需要找2到int(b ** 0.5)即可,就找全了所有的对数。这样的效率明显比从b//2开始找高很多,虽然上面的问题不是单纯找指数,还要给出最大约数,但是我们可以灵活应用
2
![](https://i-blog.csdnimg.cn/blog_migrate/7b6b3b5b1f6f59bb34b4b539caf89009.png)
你们都可以试一试结果是不是一样的。这样优化循环次数就少了很多。可能数字小看不出来效果,数字大的时候效率就差很多,因为b很大的时候b//2比b**0.5要大很多。
我加了一个n,n初始化为0(初始化可以按照你的想法任意初始化,但是必须和for下面
![](https://i-blog.csdnimg.cn/blog_migrate/78563d732765a1f4b92241a2d84f430d.png)
这个判断条件要匹配,比如我让n初始化为0,判断条件就是not n,才打印a是质数),如果for里面的if条件满足,也就是说b找到了约数,就让n=1,那么下面not in就是假,就不打印。但是这样只是很简单的情况,可能会有很复杂的情况,迫使你去使用和for或者while配套的else去完成一些操作或者说使用了和for或者while配套的else去完成这些操作会很简单,都是有可能的。所以说,else的这种用法还是值得我们去学习的。细心的小伙伴可能会发现,我上面1和2中代码有细微的不同,没错,1里面是没有用break的,2用了break,我这里也只是想说明编程是很灵活的,不一定非要用什么什么函数,其他方式也可以实现,只是效率不一样,用了break效率明显高很多,因为它会让程序提早跳出循环,执行的循环次数要少。我要再说一个东西,也就是有的时候我们会用到while 1这样永远循环的语句,你让else和它搭配是没有意义的,因为它要想循环结束,只能靠break,那么你后面搭配的else(注意一定是要和while 1搭配的else)里的语句永远不可能被执行的。拿上面一段程序为例
![](https://i-blog.csdnimg.cn/blog_migrate/31d91926d06343d5af35a6c00bc95e8a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/43f3651bee1ed1fe62122d6b9e9fbbda.png)
这个else里的c=1永远不会被执行,这个else是一条没有用的语句,还有你们要注意我这个else的缩进,它是和while1搭配的。我们实际上是可以把while 1语句改一改的,只需要加一个参数
![](https://i-blog.csdnimg.cn/blog_migrate/5b90546c294ca965060824bc86fc83b5.png)
![](https://i-blog.csdnimg.cn/blog_migrate/916a711a48ffb2b9031a2d8b9e670e8e.png)
我还是要提醒一点,m的初始化和满足跳出循环条件m的赋值和while 后面的条件要匹配,比如我初始化m=1,while 后面就是m,满足跳出循环的条件是m=0。那如果你初始化m=0,while后面就是not m,满足跳出循环的条件是m=1。这样做我就盘活了else,是else里面的语句可以被执行。
下面就讲一讲和try搭配的else,这种else是必须try里面的语句没有出现异常,才能进入到
else执行里面的语句。举个例子
![](https://i-blog.csdnimg.cn/blog_migrate/85a11b3b35c0bb5a8e5b0ba5c2a2ade1.png)
我们看到else里的a=2没有被执行。下面对比
![](https://i-blog.csdnimg.cn/blog_migrate/0894655562832713284c83f4394d3824.png)
a=2被执行了。但是我还可以不用else
![](https://i-blog.csdnimg.cn/blog_migrate/6e9b491a9aff69845a50644165e8bfe5.png)
也是ok的啊,看过上一讲的朋友应该知道为什么可以写在那里。我还是那句话,你要有足够多的只是储备去应对现实中可能发生的无数种复杂情况,有些情况我们甚至想象不到的。
最后来说一下配对问题和顺序问题
![](https://i-blog.csdnimg.cn/blog_migrate/a751f284881706e853d4d66157b5e408.png)
对比
![](https://i-blog.csdnimg.cn/blog_migrate/11a33d516977229d943bce63d37ac15c.png)
和
![](https://i-blog.csdnimg.cn/blog_migrate/e2aeec863f98353d75cd99d4e6ffc491.png)
还有
![](https://i-blog.csdnimg.cn/blog_migrate/5a64d21dadec9a1573dfbe3b8fe3e5eb.png)
说明else搭配也是就近原则,但是必须匹配最近的相同缩进等级的for 或者whil(当然如果有同缩进等级的if而且if是最近的,else就匹配到了if)。并且else必须是在for 和while语句之后。所以说else虽然花心,但是也只能一对一,2p,3p它都是玩不了的。下面是异常处理的顺序
![](https://i-blog.csdnimg.cn/blog_migrate/a8fd56a904ab7e0d64bbe0b23eb85895.png)
首先说一个上一讲没有说到的,try是不能单独使用的,也就是说可以没有finally和else,但是try必须搭配一个或者多个except语句不然会报语法错误。
![](https://i-blog.csdnimg.cn/blog_migrate/a971d8469b3f6ddf7c9fbc04ff4e3bf1.png)
因为有异常,所以只有except和finally里的代码被执行。
![](https://i-blog.csdnimg.cn/blog_migrate/dd79c2ecaaa767649cb6d31bed865c71.png)
没有报错,else和finally里面代码被执行。
![](https://i-blog.csdnimg.cn/blog_migrate/85f8ba55fd6e0ad4ef782149116b0fa7.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9dd78197a8e15b0c928c2e4d807ff027.png)
else必须放在它搭配的try对应的所有except的后面。那么else和finally顺序如何?
![](https://i-blog.csdnimg.cn/blog_migrate/5aa44dd96af613faba4626b4dcb51855.png)
else必须在try和except后面,finally前面。else就近原则这里也不讲了。和上面一样,还是强调缩进。
with语句
with不是花心的,花心只修饰else。我们来,想这样一个问题,每次打开一个文件最后都要加上close,不然可能会出错,是不是很烦。with就可以解决这个问题
![](https://i-blog.csdnimg.cn/blog_migrate/fcfe5b7a3d1ca757519aff105d361b0d.png)
如果是以前不用、with的时候,我们必须要加一个close,输入的内容才会被存进硬盘,现在with会自动为你关闭文件。但是你对这个文件的操作必须都在with的内部,否则会报错,因为文件已经关闭了嘛。除非你在外面再open一次,才能在with外面对这个文件进行操作。还有,你可以在with里面用close是不会报错的
![](https://i-blog.csdnimg.cn/blog_migrate/42a3dca0aa7643fe12e90ad0306e1ab1.png)
你用with 尝试去打开一个不存在的文件也会报错
![](https://i-blog.csdnimg.cn/blog_migrate/2d24b74382b17904342047a3a9939a7d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/27d2c18d2becfbc61e255bb3c0aa11e0.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2c4bd8781f0b10a8b53e15529a0b2fe7.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9ea66c65a0f4b96efcc8808a4afd1de1.png)
对比用了with的
![](https://i-blog.csdnimg.cn/blog_migrate/add29387b0679e35c1f5de74f927f7e9.png)
所以说使用with是一种很好的方法,它让你不用担心忘记写close或者上面那种close没有被执行的情况,它会自动帮助你关闭文件以确保内容被保存在硬盘里,断电也不会丢失。
with还可以后面带多个文件。形式如下
![](https://i-blog.csdnimg.cn/blog_migrate/0a52a3d21f7179b504878259dc91c8e1.png)
这个地方是固定格式
![](https://i-blog.csdnimg.cn/blog_migrate/05286ba11a50308abaf3c6eb67bb23b7.png)
在这里我要再吹一波异常,让你编一个简单的通讯录程序,输入一个联系人,如果通讯录没有这个联系人,就会打印输入错误,如果有,就打印出号码,通讯录以字典保存。
一般来说我们会这么写
![](https://i-blog.csdnimg.cn/blog_migrate/6e80cdd85d3dd702481919cb2989af66.png)
事实上,这样的代码效率是不高的,因为程序会两次访问字典的键,一次判断是否存在(if a in t.keys()),一次打印出号码(print(a+...t[a]))。我们可以用异常处理提高代码效率,并且还能防止Ctrl+C和Ctrl+D带来的一些问题
![](https://i-blog.csdnimg.cn/blog_migrate/8b6a7a38a6f2a4662d3ad928c7af5836.png)
红色的表示这一行有语法错误
![](https://i-blog.csdnimg.cn/blog_migrate/1e570674563ecb25e4ce1a1fadf38c4d.png)
异常类型必须加上括号
![](https://i-blog.csdnimg.cn/blog_migrate/0d7da51c8cd670995de419dee1ab9138.png)
这些括号都是可以用过编译的,但是[]和{}实际运行时会发生
![](https://i-blog.csdnimg.cn/blog_migrate/1d5ee69744879c5ea7911770f46ae640.png)
所以只能用小括号
![](https://i-blog.csdnimg.cn/blog_migrate/534d51d309a7b09f9a2f41700a9bd6d1.png)
ok的,我们用异常处理提高了代码的效率,虽然你写的代码长了那么一点,但是有些代码
不一定会运行的啊,没有异常就不会进入except。也就还多写了几个异常处理里的类型,但是用户体验好了啊,代码效率高了啊,如果多写代码可以使代码效率高,我宁愿多写几行,用我多写几行换取运行时间短,时间就是生命啊。
EasyGUI
什么是GUI?
![](https://i-blog.csdnimg.cn/blog_migrate/f0393cf27a2698c0bcea35effdf0cd3b.png)
图形用户界面的简称就是GUI。EasyGUI是一个比较简单的GUI,学习EasyGUI和我们前面学习BIF和内置方法是一样的,都是学习函数或者方法的参数类型,参数个数,参数位置,返回值。掌握了这些,你就掌握了EasyGUI。
![](https://i-blog.csdnimg.cn/blog_migrate/a7ae8eb422cd5a680c3092c8748d9a44.png)
大家一定要去看http://bbs.fishc.com/thread-46069-1-1.html。后面演示的时候上面有的就不讲了,比如说导入easygui模块的三种方法,上面都有,就不再重复了。
安装教程:
首先要调出命令行
![](https://i-blog.csdnimg.cn/blog_migrate/9201454ca5b088ff642f38f466cc6af4.png)
输入cmd
![](https://i-blog.csdnimg.cn/blog_migrate/0d84dd48d0a7199f4e0bcfbc4fe1e56d.png)
回车
![](https://i-blog.csdnimg.cn/blog_migrate/1125c342948ba3e7eb9517985c6366dc.png)
默认当前目录是C如果你把EasyGUI解压安装在别的盘,要先切换到别的盘。我是安装在D盘,输入D:,回车
![](https://i-blog.csdnimg.cn/blog_migrate/86f068787e7da9068c55c5bb3e8ea208.png)
然后切换到easygui的文件夹 ,输入cd easygui-0.96回车
![](https://i-blog.csdnimg.cn/blog_migrate/31e8f4fa4cc8f0f8ad6a155054ddca76.png)
就切换到了easygui-0.96文件夹里,你可以输入dir查看文件夹里的文件
![](https://i-blog.csdnimg.cn/blog_migrate/9a0a33e1ca8b8be55019232704e4b4e6.png)
我们要装的就是setup.py。
然后输入python.exe的路径加上setup.py最后加上install如下(我的python是安装在D盘里的)
![](https://i-blog.csdnimg.cn/blog_migrate/01fb0e59025e434265fe6e8f272c4a05.png)
就安装完毕了。安装在D:/python/Lib/site-packages里
![](https://i-blog.csdnimg.cn/blog_migrate/41b87a979f4eaa9b207f3a268b1519a1.png)
然后就可以用了。
还不懂的可以去看https://www.bilibili.com/video/av4050443/index_36.html#page=36。
如何不用IDLE运行,避免冲突?
![](https://i-blog.csdnimg.cn/blog_migrate/2daee735ea64475ba34d089f86fc6dba.png)
右键选择属性或者直接选择打开方式,选择Python Launcher那个就可以了。修改代码的时候你可以用记事本或者IDLE打开都是可以的。
![](https://i-blog.csdnimg.cn/blog_migrate/e4c7842b45670b45a689569335ffc3fa.png)
我们看第一个例子
![](https://i-blog.csdnimg.cn/blog_migrate/a868692c8a8e8440b0ca4261e035cbba.png)
运行一下看看
![](https://i-blog.csdnimg.cn/blog_migrate/9b9ab5dbf11db3372d83dc994df251c6.png)
点OK进入
![](https://i-blog.csdnimg.cn/blog_migrate/bc19f640d37031b680df3e75ce5f9d5a.png)
选一个点OK,或者没有你的本名直接选Cancel
![](https://i-blog.csdnimg.cn/blog_migrate/0d7ebb4beaad06b4b4dd5a7a76860245.png)
![](https://i-blog.csdnimg.cn/blog_migrate/80cb2e8d130fe12cf5846741e96d75e0.png)
点OK
![](https://i-blog.csdnimg.cn/blog_migrate/d8891d9499cd4d7f069981e0680c4e2c.png)
你可以点Continue继续或者Cancel退出
这个字体和框都可以修改,只需要到对应的内置方法源代码里去,我们看到那个选择框方法是
![](https://i-blog.csdnimg.cn/blog_migrate/c6a7c8fb6bf24dd5086d197838c26226.png)
我们去找easygui.py里choicebox的代码,用记事本或者IDLE打开查找choicebox,一直点下一个直到进入choicebox函数的定义,推荐使用IDLE打开,因为代码颜色区分很好,看着舒服
![](https://i-blog.csdnimg.cn/blog_migrate/9400e88010e3df100119987e53532dbe.png)
![](https://i-blog.csdnimg.cn/blog_migrate/da8b321d468d60789e7ccfb92b1f52d9.png)
一直点find next知道我们进入choicebox函数的定义
![](https://i-blog.csdnimg.cn/blog_migrate/f80740d68c37029bcedbdb625f87d15e.png)
把这个root_width里的0.8改成0.4我们来试一下
![](https://i-blog.csdnimg.cn/blog_migrate/72c87fad665bcd3ab4d6a5658c1bace1.png)
比上面窄了,高和定位位置你都可以通过上面方法来修改。
改字体如何改呢?在find里输入PROPORTIONAL—FONT
![](https://i-blog.csdnimg.cn/blog_migrate/2956b85b51511698512aaf3f3a57f7d0.png)
修改PROPORTIONAL—FONT——FAMIILY后面的参数
![](https://i-blog.csdnimg.cn/blog_migrate/c4f2fa519eee491d04c69092fcc14693.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4955b34fa9ce615fcc65bfb4ae5d3919.png)
你可以去对比,字体和上面是不一样的,只是差别很小。
其它的函数我相信你如果是前面的九讲都已经看过,上面那个中文文档应该不难看懂,里面代码实例和图都挺多的。我默认你现在已经看过了那个文档,下面我们来看几个实例。
我需要提醒一点
![](https://i-blog.csdnimg.cn/blog_migrate/9d79bad8a994db1d1e7e3971c6d5d09c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/bc9bf683e1f168962590c5b9cd8e3b99.png)
如果你在IDLE里导入一个模块,而在文件里没有导入,是会报错的,因为文件是不能够共享到IDLE里的代码,但是因为这个文件是在IDLE编译器里运行的,IDLE当然可以访问到文件的代码内容,前提是文件在IDLE里运行过,没运行过当然IDLE也不可能有这个py文件的信息。
文档里面有些地方可能有错误,比如
![](https://i-blog.csdnimg.cn/blog_migrate/e6b81b4d897646868cd76bbc07396072.png)
这个代码有问题,它只是想告诉你ccbox(cc就是continue和cancel的一个box)返回的是个布c尔值,
![](https://i-blog.csdnimg.cn/blog_migrate/90d33c3c3d1d14fa6e526c9373cc4745.png)
选continue返回1,选cancel返回的是0。不用太在意。
0.把前面猜数字的小游戏加上界面吧。
![](https://i-blog.csdnimg.cn/blog_migrate/1b16bf8b60866e789de2f1a936c370da.png)
![](https://i-blog.csdnimg.cn/blog_migrate/78c4c5809f46a410ddfa3d35a4be3341.png)
第一张图也可以用异常处理
![](https://i-blog.csdnimg.cn/blog_migrate/f067c626cb0d53c6e8719f389af0e0ac.png)
运行结果我给你们看一下吧
![](https://i-blog.csdnimg.cn/blog_migrate/922b6b884cbd2e4b057cda210eb1f21a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f7d37cbdd57d50d83d3e897a96c58d4b.png)
只给大家展示一下猜三次的情况,中途退出的情况不展示了,你们可以自己打代码去试
![](https://i-blog.csdnimg.cn/blog_migrate/04ba9f745c9f64d613ab5c8ff1a91003.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6cde2271555f292847f410465262588d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ecabc2b174602f429dd4d5a6a0782cf5.png)
1实现一个用于登记用户帐号信息的界面,带*的为必填项,要求一定要有输入并且不能是空格。
补充一个str.strip。strip最多一个参数,默认是空格,并且只去除左边和右边的空格,不去掉中间的空格。返回值为字符串,如果左边有2个空格,右边也有两个,用strip()都可以去除,需要注意的是如果最左边不是空格,左边的空格都不能被去掉。给参数就按照上面去空格的规律去给定字符。给定字符如果原字符串不存在不会报错,会原样返回原字符串。
![](https://i-blog.csdnimg.cn/blog_migrate/930298f51e1e472d1f21a3068dd08e85.png)
![](https://i-blog.csdnimg.cn/blog_migrate/93e8a50bb89232bf7a4adff056837981.png)
![](https://i-blog.csdnimg.cn/blog_migrate/cd395515b2f376499fdc111fb47e64c3.png)
点ok不会把原来填的清空而是还在
![](https://i-blog.csdnimg.cn/blog_migrate/e7768223037508f6b1cd850f956f561d.png)
我们都填点数字
![](https://i-blog.csdnimg.cn/blog_migrate/3ae8f9d0bb0387d630a88e5b06ae94b5.png)
点OK
![](https://i-blog.csdnimg.cn/blog_migrate/82a945c6cc22beb5f8476e9c0df92d63.png)
如果点NO原来信息也还是有的
![](https://i-blog.csdnimg.cn/blog_migrate/0dd30447424ae39ec3a65d00d1a35ef8.png)
如果点Yes
![](https://i-blog.csdnimg.cn/blog_migrate/6b896d53ecaeda150c0f3fd783050934.png)
显示信息添加成功。
2.提供一个用户浏览框,打开用户所选择的文本文件,如果用户修改文件,提示用户覆盖保存,另存为或者取消保存。
![](https://i-blog.csdnimg.cn/blog_migrate/8a8022ea57b2a5888c2ad418dee5da9e.png)
![](https://i-blog.csdnimg.cn/blog_migrate/fd4f96849edc2b89ab292116bce08755.png)
我就不给你们演示整个运行过程了,情况太多,你们可以自己打代码试一试上面的程序。如果你看完了这个系列前面的所有讲解,还看完了那个中文文档,即使你可能暂时写不出来上面的代码,但是看懂应该是ok的。当然上面的代码不是完美无缺的(代码的bug我可以这么说永远是修不完的,看起来没有bug只是因为你还没有遇到更复杂的环境,没有遇到更皮的用户),比如Ctrl+C和Ctrl+D这样的异常没有处理还可,还可能会有格式不兼容的文件会有UnidodeDdcodeError(上一讲我们试着用普通打开方式打开一个pickle进磁盘的文件出现的就是这种异常),你也需要对这种进行异常处理,你可以自己尝试着加进去,。
3提供一个目录浏览框,统计用户选定的目录下的各种代码文件的个数和行数,给出总共的代码数
![](https://i-blog.csdnimg.cn/blog_migrate/ee303f2ec44ad1dd4c78e69c384ed549.png)
![](https://i-blog.csdnimg.cn/blog_migrate/8ea254250ac3fa048075accc261cbb04.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f15aaf9c552a14bd4fe479a812934b93.png)
当然我没有写这么多行啊,有的是下载的,至于我写了多少,自行脑补。
这一讲4个例子源代码的百度云链接:https://pan.baidu.com/s/1sm0d1CD 密码:h06c
最后给大家推荐一个快捷键网站,里面有很多实用的快捷键哦
https://www.cnblogs.com/liyuanhong/articles/4375890.html