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