Python语法
Python 用缩进代替花括号、一切皆对象,这两条规则决定了它的语法风格和绝大多数行为。缩进不仅是排版约定,更是语法的一部分——错误缩进直接抛 IndentationError。动态类型让代码简洁,但变量绑定的真实规则(对象引用 + 作用域查找)是初学者最容易踩坑的地方。
数据类型
Python 数据类型按"是否可变"分为两大阵营,这是理解一切 Python 行为的钥匙:
| 类型 | 可变性 | 说明 |
|---|---|---|
int / float / bool | 不可变 | 数字;bool 是 int 的子类 |
str | 不可变 | Unicode 字符串,切片、拼接产生新对象 |
tuple | 不可变 | 定长序列,可哈希(可作 dict 键) |
frozenset | 不可变 | 不可变集合 |
list | 可变 | 动态数组,尾部操作 O(1) |
dict | 可变 | 哈希表,O(1) 查找 |
set | 可变 | 哈希集合,去重、成员判断 |
可变与不可变的区别在"原地修改是否会改变对象身份":list.append() 原地改,所有引用都看到变化;str 的任何修改都生成新对象。这个区别直接决定函数传参时的表现。
a = [1, 2]
b = a # b 与 a 指向同一列表
b.append(3) # a 也变成 [1, 2, 3]
s = "ab"
t = s.upper() # t 是新字符串,s 不变变量与作用域
Python 变量是"名字绑定到对象",不是"盒子装值"。赋值 x = 1 是把名字 x 绑定到整数对象 1,重新赋值只是换绑到新对象。
作用域查找遵循 LEGB 规则:Local(局部)→ Enclosing(外层函数)→ Global(模块级)→ Built-in(内置)。
count = 0 # Global
def outer():
count = 1 # Enclosing
def inner():
count = 2 # Local
return count
return inner()赋值即声明
在函数内对变量赋值,Python 默认把它当成局部变量。想改全局变量必须用 global,改外层函数变量用 nonlocal——否则会抛 UnboundLocalError(看起来是"用了未定义变量")。
count = 0
def wrong():
print(count) # ❌ UnboundLocalError:count 在函数内被赋值,被当作局部
count = 1
def right():
global count
count = 1 # ✅ 修改模块级变量控制流
if / for / while 语法与 C 系语言接近,差异在两个地方:
- 条件不需要括号,块用冒号 + 缩进
for遍历的是可迭代对象(list、dict、range、生成器),不是下标
# 遍历字典:默认遍历键
d = {"a": 1, "b": 2}
for k in d: # k = "a", "b"
print(k, d[k])
for k, v in d.items(): # 同时拿键值
print(k, v)
# range 生成整数序列
for i in range(3): # 0, 1, 2
print(i)Python 3.10+ 引入 match 语句,比 if-elif 更适合结构化匹配:
def describe(obj):
match obj:
case 0:
return "零"
case [x, y]: # 序列模式
return f"两点: {x}, {y}"
case {"name": n}: # 字典模式
return f"名字: {n}"
case _: # 兜底
return "其他"函数与参数传递
Python 函数传参传递的是"对象引用"——形参和实参指向同一对象,但重新绑定形参不影响实参。这既不是 C 的值传递,也不是 C++ 的引用传递,而是"传对象引用":
def f(lst, n):
lst.append(4) # 修改对象本身 → 外部可见
n = 99 # 重新绑定形参 → 外部 n 不变
lst = [100] # 重新绑定形参 → 外部 lst 不变
arr = [1, 2, 3]
num = 5
f(arr, num)
# arr = [1, 2, 3, 4],num = 5默认参数陷阱
默认参数只在定义时求值一次。可变默认值会被所有调用共享:
def add_item(item, bag=[]): # ❌ bag 是同一个列表
bag.append(item)
return bag
add_item("a") # ['a']
add_item("b") # ['a', 'b'] ← 上一次的结果还在正确写法用 None 占位,函数体内创建:
def add_item(item, bag=None):
if bag is None:
bag = []
bag.append(item)
return bag常用内置函数
| 函数 | 作用 | 示例 |
|---|---|---|
len() | 长度 | len("abc") → 3 |
range() | 整数序列 | list(range(3)) → [0,1,2] |
enumerate() | 带索引遍历 | list(enumerate("ab")) → [(0,'a'),(1,'b')] |
zip() | 并行打包 | list(zip([1,2],['a','b'])) → [(1,'a'),(2,'b')] |
sorted() | 排序(返回新列表) | sorted([3,1,2]) → [1,2,3] |
isinstance() | 类型检查 | isinstance(1, int) → True |
map / filter / reduce 与推导式的关系见 Python函数式编程;async/await 与 GIL 见 Python异步编程;面向对象特性见 Python 主文档。