02 语法、类型与数据模型
大约 3 分钟编程语言Python类型数据模型语法
02 语法、类型与数据模型
Python 变量不是装着值的盒子,而是指向对象的名称。理解对象、名称绑定和可变性,比背语法更重要。
1. 动态类型与运行时对象
value = 42
print(type(value))
print(isinstance(value, int))
value = "42"
print(type(value))名称可以重新绑定到不同类型,但类型注解和静态检查会帮助大型代码保持约束。
关键行为:
- 参数传递采用对象引用。
- 函数默认参数只在定义时求值一次。
- 可变对象进入多个名称或容器时,需要明确所有权。
is判断对象身份,==判断值相等。
first = [1, 2]
second = first
third = first.copy()
print(first is second)
print(first is third)
print(first == third)2. 数值与浮点误差
from decimal import Decimal
from fractions import Fraction
print(0.1 + 0.2)
print(Decimal("0.1") + Decimal("0.2"))
print(Fraction(1, 10) + Fraction(2, 10))金额和精确小数不要直接用二进制浮点做累计。若必须使用 float,用误差范围比较:
import math
print(math.isclose(0.1 + 0.2, 0.3, rel_tol=1e-9, abs_tol=1e-12))3. 真值、空值与默认值
以下值在布尔上下文中为假:False、None、0、0.0、空字符串、空容器。
def display_name(name: str | None) -> str:
if name is None:
return "anonymous"
if not name.strip():
return "anonymous"
return name.strip()判断 None 使用 is None;判断空容器使用 if not items。不要把 0 或空字符串误当成缺失值,除非业务语义确实相同。
4. 字符串、字节和编码
text = "中文"
payload = text.encode("utf-8")
print(payload)
print(payload.decode("utf-8"))常用边界:
- 文件和网络协议明确指定编码,跨系统优先 UTF-8。
str表示文本,bytes表示字节序列。- 读取第三方数据时使用
errors="replace"或严格错误处理前,先确认数据质量要求。 - 正则表达式和界面宽度不是同一个问题,中文排版不能只按字符数截断。
5. 比较与排序
from dataclasses import dataclass
@dataclass(frozen=True, order=True)
class Version:
major: int
minor: int
versions = [Version(3, 13), Version(3, 14), Version(3, 12)]
print(sorted(versions))复杂对象使用 key,不要在比较函数里混合类型:
records = [
{"name": "api", "latency_ms": 42},
{"name": "db", "latency_ms": 12},
]
print(sorted(records, key=lambda item: item["latency_ms"]))6. 类型注解是接口
from collections.abc import Iterable
def total(values: Iterable[int]) -> int:
return sum(values)注解不会自动阻止错误,但会被 IDE、mypy、pyright 和运行时工具使用。关键接口优先标注;内部短小代码不必为了形式而堆满复杂类型。
7. 不可变与可变
不可变对象通常包括 int、float、str、bytes、tuple、frozenset。可变对象包括 list、dict、set 和大多数自定义实例。
config = {"timeout": 5}
config["timeout"] = 10
coordinates = (30.1, 120.2)
new_coordinates = coordinates + (10.0,)设计配置和函数返回值时,优先把共享可变状态收窄到最小范围。
8. 常见陷阱
def append_bad(item, target=[]):
target.append(item)
return target
def append_good(item, target=None):
if target is None:
target = []
target.append(item)
return target其他高频问题:
- 用
==比较None。 - 用可变对象做默认参数。
- 混淆浅拷贝和深拷贝。
- 把能够为空的字符串和空字符串当成同一种状态。
- 用浮点数做金额累计。
