
Python3 条件控制新手实战指南WEB项目地址演示地址先聊两句条件判断这东西说白了就是让程序学会看人下菜碟。你输入用户名密码它判断对不对对了放行错了拦下——这就是最典型的条件控制。我刚开始学的时候老觉得if太简单了有啥好讲的。结果写了个用户注册的逻辑七八个if套在一起改了一个地方崩了三个功能。后来才明白条件判断不在难在怎么写得清楚、改得动。这篇文章就盯着新手容易懵的点聊。你跟着敲一遍至少不会再被缩进报错折磨半小时。一、布尔值与比较运算符快速入门条件判断绕不开布尔值——True和False首字母必须大写这个记死了。# 哪些东西自带布尔值先记住这几个print(bool(0))# Falseprint(bool(1))# Trueprint(bool())# Falseprint(bool(abc))# Trueprint(bool([]))# Falseprint(bool([1,2]))# Trueprint(bool(None))# False空的东西大多是False非空的基本是True。这条规则记住后面讲真假值判定的时候会用上。比较运算符返回的就是布尔值age20print(age18)# Trueprint(age18)# Falseprint(age!18)# TruePython支持连写比较这个写起来很舒服score85if80score90:print(良好)# 这下会打印其他语言得写成score 80 score 90Python不用。新手容易搞混的地方是赋值是判等。写if age 18直接报语法错误因为赋值语句不能出现在条件位置。我见过有人因为这个卡了二十分钟。二、if语句基础结构与缩进规范先看一个完整的if结构长啥样ageint(input(输入年龄: ))ifage18:print(你已经成年了)print(可以去考驾照了)重点说缩进。Python用缩进来表示代码块不像C/Java用大括号。同一层级的代码缩进必须一致。# 这样写会报错ifage18:print(成年了)print(这行缩进不对)# IndentationError缩进用几个空格PEP8推荐4个。但更重要的是保持统一不要这段用4个空格那段用Tab。大多数编辑器可以设置Tab转空格打开这个功能省很多事。这里有个很多人不知道的缩进不光是空格数一致空格和Tab混用会直接报错肉眼看不出来那种。VSCode右下角能看到当前文件用的是空格还是Tab如果混了会显示混合缩进。# 看起来一样但一个用了空格一个用了TabifTrue:print(这行用了4个空格)print(这行用了Tab)# 肉眼看不出来但运行报错三、elif多分支逻辑判断实战elif是else if的缩写用来处理多个互斥的条件score78ifscore90:gradeAelifscore80:gradeBelifscore70:gradeCelifscore60:gradeDelse:gradeEprint(f等级:{grade})# C注意elif的条件判断顺序是从上到下一旦匹配就停止往下走了。score78匹配到70这个分支后面的60不会再判断。很多新手会写出这样的代码# 画蛇添足ifscore90:gradeAifscore80andscore90:# 其实不需要 and score 90gradeBifscore70andscore80:gradeC用elif就干净多了而且每个条件只判断一次。上面那种写法不仅啰嗦而且score95的时候第一和第二个if都会执行虽然不影响结果但浪费性能。四、else默认处理机制应用else是以上条件都不满足时的兜底方案。很多逻辑里它充当默认值的角色# 用户输入用户名没输入就给个默认名usernameinput(请输入用户名: )ifusername.strip():username游客else:print(f欢迎回来,{username})还有错误处理的场景importre phoneinput(输入手机号: )ifre.match(r^1[3-9]\d{9}$,phone):print(手机号格式正确)else:print(手机号格式有误请重新输入)else还有个容易被忽视的用法——和循环配合。for和while可以带else循环正常走完没有被break打断就会执行else块# 查找列表中是否有某个元素items[1,2,3,4,5]target6foriteminitems:ifitemtarget:print(找到了)breakelse:print(没找到)# 循环没有被break执行这里这个写法比设一个found标志变量清爽很多。不过新手看这个容易懵先知道有这么回事就行。五、嵌套条件判断场景解析嵌套就是if里面再套if。能避免就避免但有些场景确实绕不开。一个常见的嵌套场景——先判断大条件再细化判断age25has_licenseTrueifage18:ifhas_license:print(可以租车)else:print(需要先考驾照)else:print(未成年不能租车)这种可以优化成and连接ifage18andhas_license:print(可以租车)elifage18andnothas_license:print(需要先考驾照)else:print(未成年不能租车)但嵌套太深了谁也救不了# 三层嵌套看五分钟不知道在干嘛ifcondition1:ifcondition2:ifcondition3:do_something()else:do_other()else:do_third()else:do_fourth()碰到这种代码要么提前返回如果是在函数里要么拆成多个独立的if要么重新设计逻辑。三层以上的嵌套基本意味着思路该理一理了。六、and/or/not逻辑组合技巧and全真才真。or一真就真。not取反。这部分真正的难点在于短路求值。# and 短路左边为False右边根本不会执行defexpensive_check():print(这个函数执行了)returnTrueifFalseandexpensive_check():print(不会打印)# 这个函数执行了 不会打印因为左边的False已经让整个and确定为False了# or 短路左边为True右边不执行ifTrueorexpensive_check():print(会打印)# 这个函数执行了 不会打印这个特性在写防御性代码的时候特别有用# 安全地获取嵌套字典的值user{profile:{name:张三}}ifuseranduser.get(profile)anduser[profile].get(name):print(user[profile][name])# 用短路特性简化nameuseranduser.get(profile)anduser[profile].get(name)# 如果中间某个不存在name就是False或None不会报错再比如给默认值# 如果用户没输入名字用默认值nameinput(输入名字: )or匿名用户print(name)or的短路特性让这行代码既安全又简洁。但别滥用太长的or链读起来很费劲。七、三元表达式简洁写法演示三元表达式就是把if-else压缩成一行语法是结果1 if 条件 else 结果2age20status成年ifage18else未成年print(status)# 成年这个比写四行if-else省地方适合简单的二选一赋值# 取最大值a,b10,20max_valaifabelseb# 格式化输出price99.9tip需要配送费ifprice100else免配送费但别把三元表达式搞复杂了# 让人看不懂的写法resultaifabelsebifbcelsec# 虽然能跑# 换成if-elif-else三秒钟就看懂了ifabandac:resultaelifbc:resultbelse:resultc嵌套三元表达式基本等于给后面维护的人埋雷。我个人的标准是写在一行里超过80个字符就老老实实换回if-else。八、真假值判定规则详解Python里每个对象都可以当布尔值用不光是True和False。会被判定为False的值记住这几种就够了NoneFalse数值00,0.0,0j空序列/集合,[],(),{},set(),range(0)其他所有值都是True。这个规则的妙处是你可以直接写# 不用写成 if len(name) 0name张三ifname:print(f你好,{name})else:print(名字不能为空)# 不用写成 if len(items) ! 0items[1,2,3]ifitems:print(f有{len(items)}个项目)# 不用写成 if user is not None and user ! {}user{name:张三}ifuser:print(user[name])很多新手会这样写ifnameTrue:# 多此一举ifitems![]:# 虽然能跑但不Pythoniciflen(name)0:# 可以但啰嗦记住if x比if x True更地道也比if x is True更宽松因为后者要求x必须是布尔True而if x能接受任何真值。九、常见缩进错误与排查方法条件控制相关的报错80%是缩进问题。遇到这类错误不用慌挨个排查。错误1IndentationError: expected an indented block意思是这里应该有缩进。if、elif、else、for、while、def后面的代码块必须有缩进。# 错误ifage18:print(成年了)# 缩进没对齐# 如果暂时不想写逻辑用pass占位ifage18:pass# pass就是啥也不做占位用的错误2IndentationError: unindent does not match any outer indentation level缩进级别不一致。检查前后缩进的空格数是否相同。错误3Tab和空格混用编辑器里看不出来但运行报错。排查方法VSCode右下角点击空格或Tab可以切换也能看到当前文件用的是什么用python -t运行脚本会警告Tab和空格混用编辑器设置显示空白字符就能看到所有的点和箭头实践建议编辑器设置Tab键转换为空格并且用4个空格写代码的时候盯着缩进对齐线看如果报缩进错误把这段代码的缩进全部删了重新打一遍十、用户输入验证综合案例把上面的东西串起来写一个用户注册信息验证的小程序。importredefvalidate_username(username):用户名3-12位字母数字下划线ifnotusername:returnFalse,用户名不能为空iflen(username)3orlen(username)12:returnFalse,用户名长度需为3-12位ifnotre.match(r^[a-zA-Z0-9_]$,username):returnFalse,用户名只能包含字母、数字、下划线returnTrue,用户名可用defvalidate_password(password,confirm):密码至少8位包含字母和数字ifnotpassword:returnFalse,密码不能为空iflen(password)8:returnFalse,密码至少8位ifnotre.search(r[a-zA-Z],password):returnFalse,密码需要包含字母ifnotre.search(r\d,password):returnFalse,密码需要包含数字ifpassword!confirm:returnFalse,两次输入的密码不一致returnTrue,密码可用defvalidate_email(email):邮箱简单格式验证ifnotemail:returnFalse,邮箱不能为空ifnotre.match(r^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}$,email):returnFalse,邮箱格式不正确returnTrue,邮箱格式正确defmain():print(*40)print(用户注册信息验证)print(*40)# 收集用户输入usernameinput(用户名: ).strip()passwordinput(密码: ).strip()confirminput(确认密码: ).strip()emailinput(邮箱: ).strip()# 逐项验证只要有一项失败就停止valid,msgvalidate_username(username)ifnotvalid:print(f❌{msg})returnvalid,msgvalidate_password(password,confirm)ifnotvalid:print(f❌{msg})returnvalid,msgvalidate_email(email)ifnotvalid:print(f❌{msg})return# 所有验证通过print(✅ 所有信息验证通过)print(f用户名:{username})print(f邮箱:{email})print(密码: ********)if__name____main__:main()运行效果 用户注册信息验证 用户名: 张三 ❌ 用户名只能包含字母、数字、下划线用户名: zhangsan 密码: 123456 确认密码: 123456 邮箱: zhangsanqq.com ❌ 密码需要包含字母用户名: zhangsan 密码: abc12345 确认密码: abc12345 邮箱: zhangsanqq.com ✅ 所有信息验证通过 用户名: zhangsan 邮箱: zhangsanqq.com 密码: ********这个例子把if、elif、else、and/or/not、真假值判定、比较运算符都串起来了。你可以试着改改验证规则比如用户名不能用纯数字、密码不能包含用户名之类的练练手。最后说两句条件控制说到底是让程序做选择题。代码怎么写才算好我自己的标准是别人包括三个月后的自己看一遍就能明白这段逻辑在干嘛。缩进统一用4个空格嵌套不超过三层复杂的and/or链拆成带名字的变量——这些小习惯比学会某个高级技巧重要得多。前面讲的验证案例你可以跑一遍改改规则、换换输入看看输出变化。遇到报错就看看是哪类缩进错误多折腾几次就有数了。如果卡在某个点上把这个条件拆成最简的形式一行一行打印中间结果慢慢就定位到问题了。写代码这事儿调试的时间永远比写的时间长习惯就好。