Python康复训练——控制流与函数

Python康复训练——控制流与函数 一、控制流控制流决定代码走哪条路、走几次。Python 用缩进对齐来划分代码块没有大括号也没有switch。1. if 条件判断# 控制流/if 结构ifscore60:print(不及格)elifscore80:print(及格)elifscore90:print(良好)else:print(优秀)要点if/elif/else结尾都带:后跟缩进块。elif、else可省略分支可任意扩展。Python 没有switch多分支用if-elif-else或者用字典映射来替代——查表比长串 if 更清晰。三元表达式if 表达式rankGoodifscore90elseNot bad一句话给变量赋值等价于其他语言的条件 ? a : b。2. while 循环while条件:循环体else:# 循环正常结束没被 break时才执行print(done)while的else子句是个容易被忽略的特性只有循环没有被break打断、自然走完时才会执行。一旦breakelse不跑。这个语义和多数语言不同记牢。3. for 循环foriinrange(1,8):print(i)else:print(OK)for遍历序列列表、字符串、range等每次取一个值赋给循环变量。else子句的语义和while一样正常结束才执行。4. break 与 continuebreak跳出整个循环else不会执行。continue跳过本次循环的剩余语句直接进下一轮。# 输出奇数forxinrange(1,9):ifx%20:continueprint(x)小结break管整个循环停不停continue管这一轮跳不跳else管循环是不是体面结束的。三者搭配能写出很自然的搜索逻辑。二、函数函数把一段逻辑封装起来给个名字重复调用。1. 定义与调用defsay_hi():print(Hi, everybody!)say_hi()say_hi()def 函数名(参数):后跟缩进块。函数没写return时默认返回None。2. 参数的四种形态这是函数部分的核心理清参数怎么传形态写法说明位置参数def f(x, y)按顺序传实参给形参赋值默认值参数def f(s, times1)必须放在无默认值参数后面关键字参数f(b3, a1)按名字传不用记顺序可变参数*args/**kwargs收集多余的位置/关键字参数# 可变参数* 收集成元组** 收集成字典deftotal(a5,*words,**dic):foriinwords:# words 是 tupleprint(seq:,i)fork,vindic.items():# dic 是 dictprint(%s - %s%(k,v))total(5,4,3,2,Jack12,Joe8)顺序铁律位置参数 → 默认值参数 →*args→**kwargs乱排会报错。3. return 与多返回值# 用元组一次返回多个值defswap(x,y):return(y,x)a,bswap(a,b)# 元组解包Python 没有只能返一个值的限制——靠元组装多个值调用端用解包接收。这是 Python 特有的简洁写法a, b b, a这种交换也基于此。4. 局部变量与全局变量函数内部定义的变量是局部变量作用域只在函数内。函数外部定义的是全局变量函数内可读。同名时局部优先想在函数内修改全局变量必须用global声明否则只是新建了个同名局部变量。vglobaldeffun():globalv# 声明后才能改外部的 vvlocalfun()print(v)# 输出 localglobal能不用就不用。函数依赖外部变量改值是 bug 温床也让函数难以测试和复用。5. 文档字符串docstring函数、模块、类的第一个逻辑行字符串就是它的文档存在__doc__里help()能提取。deffun_void():空函数 测试空函数 passprint(fun_void.__doc__)help(fun_void)约定第一行一句话总结第二行空行第三行起详细描述。写 docstring 是 Python 的工程素养起点——配合 FastAPI 这类框架docstring 还会直接变成接口文档。三、lambda一行函数lambda创建一个匿名函数对象接收参数返回一个表达式的值。没有return表达式本身就是返回值。# 按字典里的某个键排序data[{x:8,y:23},{x:2,y:98},{x:4,y:3}]data.sort(keylambdai:i[x])# 按 x 排典型场景当临时函数、只在一个地方用、逻辑简单排序 key、过滤条件等。逻辑复杂就老老实实写deflambda 会越写越难读。四、模块与包函数管逻辑复用模块和包管文件级组织。1. 模块导入importsys# 导入整个模块用 sys.argv 访问frommathimportsqrt# 只导入需要的名字直接用 sqrt()import 模块模块名当命名空间模块.属性访问推荐不会撞名。from ... import *把模块里所有公开名字一股脑倒进来慎用——容易和当前作用域撞名还看不出名字哪来的。Python 按sys.path列表里的目录去找模块自定义模块要放在这些路径下。2.__name__ __main__每个模块都有__name__独立运行时等于__main__被 import 时等于模块名。用这个判断来区分直接跑和被导入if__name____main__:print(本模块独立运行)else:print(本模块被其他模块导入)这是 Python 模块的惯用入口——把测试/启动代码放if __name__ __main__:里别人 import 时不会误触发。3. dir() 函数dir()返回对象定义的名称列表无参返回当前模块的名字传对象返回该对象的名字。排查这个名字从哪来很有用。4. 包包 目录 __init__.py。__init__.py告诉 Python这个目录是个包。包用来管理模块形成层级hzgj/ # 顶层包 ├── __init__.py ├── market/ # 子包 │ ├── __init__.py │ └── Pkg01.py └── product/ ├── __init__.py └── Pkg02.py导入时用点号串起来import hzgj.market.Pkg01 as p1。小结函数管逻辑模块管文件包管目录。从def到import再到包是代码组织能力的三级跳——写小脚本用函数就够工程化就得靠模块和包分层。