Python 基础语法完整汇总

16 阅读28分钟

基于 Python 3.12+(当前主流生产版本),标注了 3.10/3.11/3.12 引入的新语法。
参考来源:Python 官方语言参考Python 官方教程、PEP 文档。


一、变量与数据类型

1.1 变量赋值

# 单变量赋值
x = 10
name = "Alice"

# 多变量同时赋值
a, b, c = 1, 2, 3

# 多变量相同值
x = y = z = 0

# 解包赋值
first, *rest = [1, 2, 3, 4, 5]  # first=1, rest=[2,3,4,5]
*head, last = [1, 2, 3, 4, 5]   # head=[1,2,3,4], last=5
first, *middle, last = [1, 2, 3, 4, 5]  # first=1, middle=[2,3,4], last=5

# 交换变量(不需要临时变量)
a, b = b, a

1.2 数据类型总览

类型说明示例
int整数,无大小限制42, -7, 10**100
float64 位双精度浮点数3.14, 1e10, float('inf')
complex复数3+4j, complex(1, 2)
bool布尔值(int 的子类)True, False
strUnicode 字符串(不可变)"hello", 'world'
bytes字节串(不可变)b"hello", bytes([65, 66])
bytearray字节串(可变)bytearray(b"hello")
NoneType空值None

1.3 类型检查与转换

# 类型检查
type(42)          # <class 'int'>
isinstance(42, int)  # True
isinstance(True, int)  # True(bool 是 int 的子类)

# 类型转换
int("42")         # 42
int(3.9)          # 3(截断,不是四舍五入)
float("3.14")     # 3.14
str(42)           # "42"
bool(0)           # False
bool("")          # False
bool([])          # False
bool(None)        # False
bool("hello")     # True
bool([1, 2])      # True

⚠️ Python 是动态类型语言:变量没有类型声明,类型绑定在对象上而非变量上。同一个变量可以先后绑定不同类型的对象。

1.4 数值运算

# 算术运算
10 / 3       # 3.333...(真除法,始终返回 float)
10 // 3      # 3(整除/地板除)
10 % 3       # 1(取模)
2 ** 10      # 1024(幂运算)

# 比较运算
x == y       # 值相等
x != y       # 值不等
x is y       # 同一对象(身份比较)
x is not y   # 不同对象

# 链式比较(Python 独有语法糖)
1 < x < 10   # 等价于 1 < x and x < 10
a <= b < c   # 等价于 a <= b and b < c

# 位运算
5 & 3        # 1(按位与)
5 | 3        # 7(按位或)
5 ^ 3        # 6(按位异或)
~5           # -6(按位取反)
5 << 1       # 10(左移)
5 >> 1       # 2(右移)

1.5 海象运算符(Python 3.8+)

# := 在表达式中赋值
import re
if (match := re.search(r'\d+', "abc123def")):
    print(match.group())  # "123"

# 在 while 循环中使用
while (line := input(">>> ")) != "quit":
    print(f"You said: {line}")

# 在列表推导式中过滤
results = [y for x in data if (y := f(x)) > 0]

二、字符串(str)

2.1 字符串创建

# 单引号、双引号(完全等价)
s1 = 'hello'
s2 = "hello"

# 三引号:多行字符串
s3 = """这是
多行
字符串"""

# 原始字符串(不处理转义)
path = r"C:\Users\name\file.txt"  # 反斜杠不转义
regex = r"\d+.\d+"               # 正则表达式常用

# 字节串
b = b"hello"        # bytes 类型
b2 = "hello".encode("utf-8")  # str → bytes
s = b.decode("utf-8")         # bytes → str

2.2 f-string 格式化(Python 3.6+,3.12 大幅增强)

name = "Alice"
age = 30
pi = 3.14159265

# 基础用法
f"Hello, {name}!"                    # "Hello, Alice!"
f"Next year: {age + 1}"              # "Next year: 31"
f"Pi: {pi:.2f}"                      # "Pi: 3.14"(格式化规范)
f"{'hello':>10}"                     # "     hello"(右对齐,宽度10)
f"{'hello':<10}"                     # "hello     "(左对齐)
f"{'hello':^10}"                     # "  hello   "(居中)
f"{42:08d}"                          # "00000042"(补零)
f"{1000000:,}"                       # "1,000,000"(千分位)
f"{0.25:.1%}"                        # "25.0%"(百分比)

# 调试模式(Python 3.8+)
f"{name=}"                           # "name='Alice'"
f"{age=}"                            # "age=30"
f"{pi=:.2f}"                         # "pi=3.14"

# Python 3.12+:表达式中可以复用引号、包含反斜杠、多行
songs = ['A', 'B', 'C']
f"Songs: {", ".join(songs)}"         # "Songs: A, B, C"
f"Lines: {"\n".join(songs)}"         # 反斜杠在表达式中合法
f"""{
    name
    .upper()
}"""                                  # 多行表达式

2.3 字符串方法(常用)

s = "  Hello, World!  "

# 查找与替换
s.find("World")       # 8(找不到返回 -1)
s.index("World")      # 8(找不到抛 ValueError)
s.count("l")          # 3
s.replace("World", "Python")  # "  Hello, Python!  "
s.startswith("  He")  # True
s.endswith("!  ")     # True

# 大小写
s.upper()             # "  HELLO, WORLD!  "
s.lower()             # "  hello, world!  "
s.title()             # "  Hello, World!  "
s.capitalize()        # "  hello, world!  "
s.swapcase()          # "  hELLO, wORLD!  "

# 去除空白
s.strip()             # "Hello, World!"
s.lstrip()            # "Hello, World!  "
s.rstrip()            # "  Hello, World!"

# 分割与拼接
"hello world".split()           # ['hello', 'world']
"a,b,c".split(",")              # ['a', 'b', 'c']
"a,b,c".split(",", maxsplit=1)  # ['a', 'b,c']
",".join(["a", "b", "c"])       # "a,b,c"

# 判断
"hello".isalpha()     # True(全是字母)
"123".isdigit()       # True(全是数字)
"abc123".isalnum()    # True(字母或数字)
"  ".isspace()        # True

# Python 3.9+:去除前缀/后缀
"TestHook".removeprefix("Test")   # "Hook"
"TestHook".removesuffix("Hook")   # "Test"

# 填充
"42".zfill(5)         # "00042"
"hi".center(10, "-")  # "----hi----"
"hi".ljust(10, "-")   # "hi--------"
"hi".rjust(10, "-")   # "--------hi"

2.4 字符串是不可变的

s = "hello"
# s[0] = "H"  # ❌ TypeError: 'str' object does not support item assignment
s = "H" + s[1:]  # ✅ 创建新字符串 "Hello"

三、数据结构

3.1 列表(list)—— 有序、可变、可重复

# 创建
nums = [1, 2, 3, 4, 5]
empty = []
from_range = list(range(10))       # [0, 1, 2, ..., 9]
from_str = list("hello")           # ['h', 'e', 'l', 'l', 'o']

# 访问(索引从 0 开始,支持负索引)
nums[0]       # 1(第一个)
nums[-1]      # 5(最后一个)
nums[-2]      # 4(倒数第二个)

# 切片 [start:stop:step](左闭右开)
nums[1:3]     # [2, 3]
nums[:3]      # [1, 2, 3](从头开始)
nums[3:]      # [4, 5](到末尾)
nums[::2]     # [1, 3, 5](步长2)
nums[::-1]    # [5, 4, 3, 2, 1](反转)
nums[1:4:2]   # [2, 4]

# 修改
nums[0] = 10              # [10, 2, 3, 4, 5]
nums[1:3] = [20, 30]      # [10, 20, 30, 4, 5]
nums[1:3] = []            # [10, 4, 5](删除切片)

# 添加
nums.append(6)            # 末尾添加
nums.insert(0, 0)         # 指定位置插入
nums.extend([7, 8])       # 扩展(追加多个元素)
nums += [9, 10]           # 等价于 extend

# 删除
nums.pop()                # 删除并返回最后一个
nums.pop(0)               # 删除并返回指定索引
nums.remove(10)           # 删除第一个值为 10 的元素
del nums[0]               # 删除指定索引
del nums[1:3]             # 删除切片
nums.clear()              # 清空列表

# 查找
3 in nums                 # True / False(成员测试)
nums.index(3)             # 返回第一个匹配的索引(不存在抛 ValueError)
nums.count(3)             # 出现次数

# 排序
nums.sort()               # 原地排序(修改原列表)
nums.sort(reverse=True)   # 降序
nums.sort(key=len)        # 自定义排序键
sorted(nums)              # 返回新列表,不修改原列表
sorted(nums, reverse=True)

# 其他
nums.reverse()            # 原地反转
len(nums)                 # 长度
min(nums), max(nums)      # 最小/最大值
sum(nums)                 # 求和(仅限数值)
list(zip([1,2], ['a','b']))  # [(1,'a'), (2,'b')]
list(enumerate(['a','b']))   # [(0,'a'), (1,'b')]

3.2 元组(tuple)—— 有序、不可变、可重复

# 创建
t = (1, 2, 3)
t2 = 1, 2, 3          # 省略括号也可以
single = (42,)         # 单元素元组必须加逗号
empty = ()
from_list = tuple([1, 2, 3])

# 访问(和列表一样,支持索引和切片)
t[0]       # 1
t[-1]      # 3
t[1:]      # (2, 3)

# 解包
a, b, c = (1, 2, 3)
first, *rest = (1, 2, 3, 4)  # first=1, rest=[2,3,4]

# 命名元组(带字段名的元组)
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(1, 2)
p.x        # 1
p.y        # 2
p[0]       # 1(仍然支持索引访问)

💡 何时用元组而非列表:数据不应被修改时(如坐标、数据库查询返回的行、字典的键、函数返回多个值)。元组比列表更省内存、更快,且可以作为字典的键(列表不行)。

3.3 字典(dict)—— 键值对、无序(Python 3.7+ 保证插入顺序)、键唯一

# 创建
d = {"name": "Alice", "age": 30}
d2 = dict(name="Alice", age=30)
d3 = dict([("name", "Alice"), ("age", 30)])
empty = {}

# 访问
d["name"]               # "Alice"(键不存在抛 KeyError)
d.get("name")           # "Alice"(键不存在返回 None)
d.get("gender", "N/A")  # "N/A"(键不存在返回默认值)

# 修改/添加
d["age"] = 31           # 修改已有键
d["gender"] = "F"       # 添加新键
d.update({"age": 32, "city": "Beijing"})  # 批量更新
d |= {"score": 100}     # Python 3.9+:合并运算符

# 删除
del d["age"]            # 删除指定键(不存在抛 KeyError)
d.pop("name")           # 删除并返回值(不存在抛 KeyError)
d.pop("name", None)     # 删除并返回值(不存在返回默认值)
d.popitem()             # 删除并返回最后一个插入的 (key, value)

# 遍历
for key in d:                    # 遍历键
    print(key)
for value in d.values():         # 遍历值
    print(value)
for key, value in d.items():     # 遍历键值对
    print(f"{key}: {value}")

# 查找
"name" in d             # True(检查键是否存在)
"name" not in d         # False

# 其他
len(d)                  # 键值对数量
list(d.keys())          # 所有键
list(d.values())        # 所有值
list(d.items())         # 所有键值对

# 字典推导式
squares = {x: x**2 for x in range(5)}  # {0:0, 1:1, 2:4, 3:9, 4:16}

# Python 3.9+:合并运算符
d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}
d1 | d2   # {"a": 1, "b": 3, "c": 4}(d2 覆盖 d1 的同名键)
d1 |= d2  # 就地更新 d1

# defaultdict(默认值字典)
from collections import defaultdict
dd = defaultdict(list)
dd["fruits"].append("apple")   # 不需要先检查键是否存在
dd["fruits"].append("banana")
# dd = {"fruits": ["apple", "banana"]}

# Counter(计数器)
from collections import Counter
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]
c = Counter(words)   # Counter({"apple": 3, "banana": 2, "cherry": 1})
c.most_common(2)     # [("apple", 3), ("banana", 2)]

3.4 集合(set)—— 无序、不可变元素、唯一

# 创建
s = {1, 2, 3, 4, 5}
s2 = set([1, 2, 2, 3])  # {1, 2, 3}(自动去重)
empty_set = set()        # 注意:{} 是空字典,不是空集合

# 添加/删除
s.add(6)
s.remove(1)     # 不存在抛 KeyError
s.discard(99)   # 不存在不报错
s.pop()         # 随机删除并返回一个元素
s.clear()

# 成员测试(O(1) 时间复杂度,比列表快得多)
3 in s          # True

# 集合运算
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

a | b    # {1, 2, 3, 4, 5, 6}  并集
a & b    # {3, 4}               交集
a - b    # {1, 2}               差集(在a不在b)
b - a    # {5, 6}               差集(在b不在a)
a ^ b    # {1, 2, 5, 6}         对称差集(不共有的元素)

# 子集/超集判断
{1, 2} <= {1, 2, 3}    # True(子集)
{1, 2} < {1, 2, 3}     # True(真子集)
{1, 2, 3} >= {1, 2}    # True(超集)

# frozenset(不可变集合,可以作为字典的键)
fs = frozenset([1, 2, 3])

3.5 数据结构选择指南

需求选择原因
有序集合,需要修改list索引访问 O(1),末尾追加 O(1)
不可变序列tuple更安全,可作字典键,更省内存
键值映射dict键查找 O(1)
去重 / 成员测试set查找 O(1),自动去重
需要默认值的字典defaultdict省去 if key not in dict 判断
需要计数Counter自带 most_common() 等方法
需要按插入顺序的字典dict(3.7+ 保证)不需要 OrderedDict
双端队列(两端高效增删)collections.deque两端操作 O(1),列表头部插入 O(n)

四、条件语句

# 基本 if-elif-else
score = 85
if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
else:
    grade = "D"

# 三元表达式(条件表达式)
status = "adult" if age >= 18 else "minor"

# 真值测试规则(以下值为 False)
bool(False)      # False
bool(None)       # False
bool(0)          # False(包括 0, 0.0, 0j)
bool("")         # False(空字符串)
bool(b"")        # False(空字节串)
bool([])         # False(空列表)
bool(())         # False(空元组)
bool({})         # False(空字典)
bool(set())      # False(空集合)
# 其他所有值都为 True

# 逻辑运算符(短路求值)
x and y    # x 为假返回 x,否则返回 y
x or y     # x 为真返回 x,否则返回 y
not x      # 布尔取反

# 海象运算符在条件中使用(Python 3.8+)
if (n := len(data)) > 10:
    print(f"Data is too long ({n} items)")

# 模式匹配 match-case(Python 3.10+)
# 详见下方"模式匹配"章节

五、循环

5.1 for 循环

# 遍历列表
for item in [1, 2, 3]:
    print(item)

# 遍历字符串
for char in "hello":
    print(char)

# range(start, stop, step)
for i in range(5):          # 0, 1, 2, 3, 4
    print(i)
for i in range(2, 8):       # 2, 3, 4, 5, 6, 7
    print(i)
for i in range(0, 10, 2):   # 0, 2, 4, 6, 8
    print(i)
for i in range(10, 0, -1):  # 10, 9, 8, ..., 1
    print(i)

# enumerate(同时获取索引和值)
for i, item in enumerate(["a", "b", "c"]):
    print(f"{i}: {item}")   # 0: a, 1: b, 2: c
for i, item in enumerate(["a", "b", "c"], start=1):
    print(f"{i}: {item}")   # 1: a, 2: b, 3: c

# zip(并行遍历多个序列)
names = ["Alice", "Bob"]
ages = [30, 25]
for name, age in zip(names, ages):
    print(f"{name} is {age}")

# 遍历字典
for key in d:
    print(key)
for key, value in d.items():
    print(f"{key}: {value}")

# 遍历集合
for item in {1, 2, 3}:
    print(item)

5.2 while 循环

count = 0
while count < 5:
    print(count)
    count += 1

# while-else(循环正常结束时执行 elsebreak 跳出则不执行)
while count < 10:
    count += 1
    if count == 5:
        break
else:
    print("循环正常结束")  # 不会执行,因为 break

5.3 循环控制

# break:跳出当前循环
for i in range(10):
    if i == 5:
        break
    print(i)  # 0, 1, 2, 3, 4

# continue:跳过本次迭代
for i in range(5):
    if i == 2:
        continue
    print(i)  # 0, 1, 3, 4

# pass:空操作占位符
for i in range(5):
    pass  # TODO: 稍后实现

# for-else / while-else(循环正常结束时执行 else)
for i in range(10):
    if i == 5:
        break
else:
    print("没有找到")  # break 了,不执行

for i in range(10):
    if i == 100:
        break
else:
    print("遍历完成,没有找到")  # 正常结束,执行

5.4 推导式(Comprehensions)

# 列表推导式
squares = [x**2 for x in range(10)]                    # [0, 1, 4, 9, ..., 81]
evens = [x for x in range(20) if x % 2 == 0]          # [0, 2, 4, ..., 18]
flat = [x for row in matrix for x in row]              # 嵌套展平

# 字典推导式
word_lengths = {word: len(word) for word in ["hi", "hello", "hey"]}
# {"hi": 2, "hello": 5, "hey": 3}
inverted = {v: k for k, v in original_dict.items()}    # 反转键值

# 集合推导式
unique_lengths = {len(word) for word in ["hi", "hey", "hello"]}
# {2, 3, 5}

# 生成器表达式(用圆括号,惰性求值,不立即创建列表)
total = sum(x**2 for x in range(1000000))  # 不占用内存

六、函数

6.1 基础定义

def greet(name: str) -> str:
    """向指定的人打招呼。"""  # docstring
    return f"Hello, {name}!"

result = greet("Alice")  # "Hello, Alice!"

6.2 参数类型

# 位置参数
def f(a, b):
    return a + b
f(1, 2)  # 3

# 默认参数(注意:默认值不要用可变对象!)
def append_to(item, target=[]):  # ❌ 危险!默认值只创建一次
    target.append(item)
    return target

def append_to(item, target=None):  # ✅ 正确做法
    if target is None:
        target = []
    target.append(item)
    return target

# 关键字参数
def profile(name, age, city="Beijing"):
    print(f"{name}, {age}, {city}")
profile("Alice", 30)                    # 使用默认值
profile("Bob", 25, city="Shanghai")     # 关键字传参

# *args:接收任意数量的位置参数(打包为元组)
def sum_all(*args):
    return sum(args)
sum_all(1, 2, 3, 4)  # 10

# **kwargs:接收任意数量的关键字参数(打包为字典)
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")
print_info(name="Alice", age=30, city="Beijing")

# 混合使用(顺序:位置参数 → *args → 关键字参数 → **kwargs)
def f(a, b, *args, key1="default", **kwargs):
    print(a, b, args, key1, kwargs)
f(1, 2, 3, 4, key1="custom", extra="data")
# 1 2 (3, 4) custom {'extra': 'data'}

# 仅位置参数(Python 3.8+,用 / 标记)
def f(a, b, /, c, d):
    pass
f(1, 2, c=3, d=4)    # ✅
# f(1, 2, 3, 4)      # ✅
# f(a=1, b=2, c=3, d=4)  # ❌ a, b 只能按位置传

# 仅关键字参数(用 * 标记)
def f(a, b, *, key1, key2="default"):
    pass
f(1, 2, key1=3)       # ✅
# f(1, 2, 3)          # ❌ key1 必须用关键字传

6.3 返回值

# 返回单个值
def add(a, b):
    return a + b

# 返回多个值(实际是返回元组)
def divide(a, b):
    return a // b, a % b
quotient, remainder = divide(10, 3)  # 3, 1

# 没有 return 或 return 后无值 → 返回 None
def do_nothing():
    pass
result = do_nothing()  # None

# 提前返回
def find_first_even(nums):
    for n in nums:
        if n % 2 == 0:
            return n
    return None  # 没找到

6.4 作用域(LEGB 规则)

# L: Local(函数内部)
# E: Enclosing(外层函数)
# G: Global(模块级别)
# B: Built-in(内置名称)

x = "global"

def outer():
    x = "enclosing"
    
    def inner():
        x = "local"
        print(x)  # "local"
    
    inner()
    print(x)  # "enclosing"

outer()
print(x)  # "global"

# global 声明:在函数内修改全局变量
count = 0
def increment():
    global count
    count += 1

# nonlocal 声明:在嵌套函数中修改外层函数的变量
def counter():
    count = 0
    def increment():
        nonlocal count
        count += 1
    return increment

6.5 Lambda 表达式

# 匿名函数(单行表达式)
square = lambda x: x ** 2
square(5)  # 25

add = lambda a, b: a + b
add(1, 2)  # 3

# 常用作排序键
students = [("Alice", 85), ("Bob", 92), ("Charlie", 78)]
students.sort(key=lambda s: s[1], reverse=True)
# [("Bob", 92), ("Alice", 85), ("Charlie", 78)]

# 配合高阶函数
list(map(lambda x: x*2, [1, 2, 3]))        # [2, 4, 6]
list(filter(lambda x: x > 0, [-1, 0, 1]))  # [1]

6.6 高阶函数

# map:对每个元素应用函数
list(map(str, [1, 2, 3]))  # ["1", "2", "3"]

# filter:过滤元素
list(filter(lambda x: x > 0, [-2, -1, 0, 1, 2]))  # [1, 2]

# sorted:自定义排序
sorted(["banana", "apple", "cherry"], key=len)
# ["apple", "banana", "cherry"]

# functools.reduce:累积计算
from functools import reduce
reduce(lambda a, b: a + b, [1, 2, 3, 4])  # 10

# functools.partial:偏函数(固定部分参数)
from functools import partial
double = partial(lambda x, y: x * y, 2)
double(5)  # 10

七、面向对象编程

7.1 类定义

class Dog:
    """一只狗的类。"""  # 类文档字符串
    
    # 类属性(所有实例共享)
    species = "Canis familiaris"
    
    # 初始化方法(构造函数)
    def __init__(self, name: str, age: int):
        # 实例属性
        self.name = name
        self.age = age
    
    # 实例方法(第一个参数是 self)
    def bark(self) -> str:
        return f"{self.name} says Woof!"
    
    # 另一个实例方法
    def description(self) -> str:
        return f"{self.name} is {self.age} years old"
    
    # 特殊方法(魔术方法)
    def __str__(self) -> str:
        return f"Dog({self.name}, {self.age})"
    
    def __repr__(self) -> str:
        return f"Dog(name={self.name!r}, age={self.age})"

# 创建实例
my_dog = Dog("Rex", 3)
my_dog.bark()         # "Rex says Woof!"
print(my_dog)         # "Dog(Rex, 3)"(调用 __str__)

7.2 继承

class Animal:
    def __init__(self, name: str):
        self.name = name
    
    def speak(self) -> str:
        raise NotImplementedError("子类必须实现 speak()")

class Cat(Animal):
    def __init__(self, name: str, indoor: bool = True):
        super().__init__(name)  # 调用父类 __init__
        self.indoor = indoor
    
    def speak(self) -> str:
        return f"{self.name} says Meow!"

class Dog(Animal):
    def speak(self) -> str:
        return f"{self.name} says Woof!"

# 多态
animals = [Cat("Whiskers"), Dog("Rex")]
for animal in animals:
    print(animal.speak())

# 多继承
class Flyable:
    def fly(self):
        return f"{self.name} is flying"

class FlyingCat(Cat, Flyable):
    pass

fc = FlyingCat("Luna")
fc.speak()  # "Luna says Meow!"(来自 Cat)
fc.fly()    # "Luna is flying"(来自 Flyable)

# MRO(方法解析顺序)
FlyingCat.__mro__  # (FlyingCat, Cat, Animal, Flyable, object)

7.3 类方法、静态方法、属性

class Temperature:
    _count = 0  # 类属性(私有约定)
    
    def __init__(self, celsius: float):
        self._celsius = celsius
        Temperature._count += 1
    
    # @property:将方法变为只读属性
    @property
    def fahrenheit(self) -> float:
        return self._celsius * 9/5 + 32
    
    @property
    def celsius(self) -> float:
        return self._celsius
    
    # @setter:允许修改属性
    @celsius.setter
    def celsius(self, value: float):
        if value < -273.15:
            raise ValueError("温度不能低于绝对零度")
        self._celsius = value
    
    # @classmethod:类方法(第一个参数是 cls)
    @classmethod
    def from_fahrenheit(cls, f: float) -> "Temperature":
        return cls((f - 32) * 5/9)
    
    # @staticmethod:静态方法(不需要 self 或 cls)
    @staticmethod
    def is_freezing(celsius: float) -> bool:
        return celsius <= 0
    
    # 类方法获取实例数
    @classmethod
    def get_count(cls) -> int:
        return cls._count

t = Temperature(100)
t.fahrenheit     # 212.0(像属性一样访问,不需要加括号)
t.celsius = 0    # 通过 setter 设置
t.celsius = -300 # ❌ ValueError
t2 = Temperature.from_fahrenheit(32)  # 通过类方法创建
Temperature.is_freezing(0)  # True(静态方法)

7.4 dataclass(Python 3.7+)

from dataclasses import dataclass, field

@dataclass
class User:
    name: str
    age: int
    email: str = "unknown"
    tags: list[str] = field(default_factory=list)  # 可变默认值必须用 field

    # 自动生成:__init__、__repr__、__eq__、__hash__(如果 frozen)

u1 = User("Alice", 30, "alice@example.com")
u2 = User("Alice", 30, "alice@example.com")
u1 == u2  # True(自动基于字段比较)
print(u1)  # User(name='Alice', age=30, email='alice@example.com', tags=[])

# frozen=True:不可变(类似命名元组,但更灵活)
@dataclass(frozen=True)
class Point:
    x: float
    y: float

p = Point(1.0, 2.0)
# p.x = 3.0  # ❌ FrozenInstanceError

# 可以用作字典的键(因为 frozen + 自动 __hash__)
locations = {Point(0, 0): "origin", Point(1, 1): "diagonal"}

# slots=True(Python 3.10+):减少内存占用
@dataclass(slots=True)
class Sensor:
    id: int
    value: float

# order=True:自动生成 __lt__、__le__、__gt__、__ge__
@dataclass(order=True)
class Score:
    value: float
    name: str = field(compare=False)  # 不参与比较

scores = [Score(85, "Alice"), Score(92, "Bob"), Score(78, "Charlie")]
sorted(scores)  # 按 value 排序

7.5 抽象类

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self) -> float:
        """计算面积。"""
        pass
    
    @abstractmethod
    def perimeter(self) -> float:
        """计算周长。"""
        pass

class Circle(Shape):
    def __init__(self, radius: float):
        self.radius = radius
    
    def area(self) -> float:
        return 3.14159 * self.radius ** 2
    
    def perimeter(self) -> float:
        return 2 * 3.14159 * self.radius

# shape = Shape()  # ❌ TypeError: 不能实例化抽象类
c = Circle(5)      # ✅ 实现了所有抽象方法

7.6 常用魔术方法

方法触发方式用途
__init__(self, ...)MyClass()初始化
__str__(self)str(obj) / print(obj)用户友好的字符串表示
__repr__(self)repr(obj) / 交互式显示开发者友好的字符串表示
__len__(self)len(obj)长度
__getitem__(self, key)obj[key]索引/键访问
__setitem__(self, key, val)obj[key] = val索引/键赋值
__delitem__(self, key)del obj[key]删除元素
__contains__(self, item)item in obj成员测试
__iter__(self)for x in obj迭代
__next__(self)next(iterator)获取下一个元素
__eq__(self, other)obj1 == obj2相等比较
__hash__(self)hash(obj)哈希(用于 dict/set 键)
__lt__, __le__, __gt__, __ge__<, <=, >, >=大小比较
__add__(self, other)obj1 + obj2加法
__enter__ / __exit__with obj:上下文管理器
__call__(self, ...)obj()让实例可调用
__bool__(self)bool(obj)布尔值(默认 __len__ 为 0 则 False)

八、异常处理

8.1 基本语法

try:
    result = 10 / 0
except ZeroDivisionError:
    print("不能除以零")
except (TypeError, ValueError) as e:
    print(f"类型或值错误: {e}")
except Exception as e:
    print(f"其他错误: {e}")
else:
    print("没有异常时执行")  # 可选
finally:
    print("无论如何都执行")  # 可选,常用于清理资源

8.2 异常层次结构

BaseException
├── SystemExit
├── KeyboardInterrupt
├── GeneratorExit
└── Exception              ← 通常只捕获这个
    ├── ArithmeticError
    │   ├── ZeroDivisionError
    │   ├── OverflowError
    │   └── FloatingPointError
    ├── AttributeError
    ├── IOError / OSError
    │   ├── FileNotFoundError
    │   ├── PermissionError
    │   └── TimeoutError
    ├── ImportError
    │   └── ModuleNotFoundError
    ├── LookupError
    │   ├── IndexError
    │   └── KeyError
    ├── NameError
    │   └── UnboundLocalError
    ├── TypeError
    ├── ValueError
    │   └── UnicodeDecodeError
    └── RuntimeError
        ├── NotImplementedError
        └── RecursionError

⚠️ 永远不要裸 except: ,这会连 KeyboardInterruptSystemExit 都捕获。至少写 except Exception:

8.3 自定义异常

class AppError(Exception):
    """应用基础异常。"""
    pass

class ValidationError(AppError):
    """数据校验异常。"""
    def __init__(self, field: str, message: str):
        self.field = field
        self.message = message
        super().__init__(f"Field '{field}': {message}")

class NotFoundError(AppError):
    """资源未找到异常。"""
    pass

# 使用
try:
    raise ValidationError("email", "格式不正确")
except ValidationError as e:
    print(e.field)     # "email"
    print(e.message)   # "格式不正确"
    print(e)           # "Field 'email': 格式不正确"

8.4 异常链(Exception Chaining)

try:
    result = 10 / 0
except ZeroDivisionError as e:
    raise ValueError("计算失败") from e
    # 输出会显示原始异常和新的异常,用 "The above exception was the direct cause" 连接

# raise ... from None:隐藏原始异常
try:
    result = 10 / 0
except ZeroDivisionError:
    raise ValueError("计算失败") from None

8.5 异常组(Python 3.11+)

# 同时处理多个异常
try:
    raise ExceptionGroup("多个错误", [
        ValueError("值错误"),
        TypeError("类型错误"),
    ])
except* ValueError as eg:
    for e in eg.exceptions:
        print(f"ValueError: {e}")
except* TypeError as eg:
    for e in eg.exceptions:
        print(f"TypeError: {e}")

8.6 BaseException.add_note()(Python 3.11+)

try:
    1 / 0
except ZeroDivisionError as e:
    e.add_note("发生在计算平均值时")
    e.add_note(f"输入数据: {data}")
    raise
# 异常回溯中会显示附加的 note 信息

九、模块与包

9.1 导入语法

# 导入整个模块
import os
import sys
os.path.join("/home", "user")

# 导入指定内容
from os.path import join, exists
from collections import defaultdict, Counter

# 别名
import numpy as np
from datetime import datetime as dt
from typing import Optional as Opt

# 相对导入(包内部使用)
from . import utils            # 同包下的 utils 模块
from .. import config          # 上级包的 config 模块
from .utils import helper      # 同包下 utils 模块的 helper 函数

# 导入所有(不推荐,会污染命名空间)
from module import *

9.2 包结构

my_package/
├── __init__.py          # 标记为包(可以为空)
├── module_a.py
├── module_b.py
└── sub_package/
    ├── __init__.py
    └── module_c.py

9.3 __init__.py 的作用

# my_package/__init__.py
# 控制 from my_package import * 时导出什么
__all__ = ["module_a", "module_b"]

# 也可以在这里做包级别的初始化
from .module_a import SomeClass
# 这样用户可以直接 from my_package import SomeClass

9.4 if __name__ == "__main__" 模式

# my_script.py
def main():
    print("Running as script")

if __name__ == "__main__":
    main()
    # 只有直接运行 python my_script.py 时才执行
    # 被 import 时不执行

十、文件操作

10.1 文本文件

# 写入(推荐用 with 自动关闭)
with open("output.txt", "w", encoding="utf-8") as f:
    f.write("Hello\n")
    f.write("World\n")
    f.writelines(["Line 1\n", "Line 2\n"])

# 读取全部内容
with open("input.txt", "r", encoding="utf-8") as f:
    content = f.read()

# 按行读取(推荐,内存友好)
with open("input.txt", "r", encoding="utf-8") as f:
    for line in f:
        print(line.strip())

# 读取所有行到列表
with open("input.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()

# 追加模式
with open("log.txt", "a", encoding="utf-8") as f:
    f.write("New log entry\n")

10.2 文件模式

模式说明
"r"只读(默认)
"w"写入(覆盖)
"a"追加
"x"创建(文件已存在则报错)
"b"二进制模式(与上面组合,如 "rb""wb"
"t"文本模式(默认,与上面组合,如 "rt"
"r+"读写
"w+"读写(覆盖)

10.3 JSON 文件

import json

# 写入 JSON
data = {"name": "Alice", "age": 30, "tags": ["python", "ai"]}
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=2, ensure_ascii=False)

# 读取 JSON
with open("data.json", "r", encoding="utf-8") as f:
    data = json.load(f)

# 字符串 ↔ JSON
json_str = json.dumps(data, indent=2)   # dict → str
parsed = json.loads(json_str)           # str → dict

10.4 CSV 文件

import csv

# 写入
with open("data.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(["name", "age", "city"])
    writer.writerow(["Alice", 30, "Beijing"])
    writer.writerows([["Bob", 25, "Shanghai"], ["Charlie", 35, "Shenzhen"]])

# 读取
with open("data.csv", "r", encoding="utf-8") as f:
    reader = csv.reader(f)
    header = next(reader)  # 跳过表头
    for row in reader:
        print(row)

# DictReader / DictWriter(用字典操作)
with open("data.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["name"], row["age"])

10.5 pathlib(面向对象的路径操作,推荐替代 os.path)

from pathlib import Path

# 创建路径
p = Path("/home/user/documents")
p = Path.home()                    # 用户主目录
p = Path.cwd()                     # 当前工作目录
p = Path("data") / "sub" / "file.txt"  # 路径拼接(推荐)

# 路径组件
p.name       # "file.txt"(文件名)
p.stem       # "file"(不含扩展名)
p.suffix     # ".txt"(扩展名)
p.parent     # Path("data/sub")
p.parts      # ("data", "sub", "file.txt")

# 判断
p.exists()       # 是否存在
p.is_file()      # 是否是文件
p.is_dir()       # 是否是目录
p.is_absolute()  # 是否是绝对路径

# 文件操作
p.read_text(encoding="utf-8")      # 读取文本
p.read_bytes()                      # 读取字节
p.write_text("hello", encoding="utf-8")  # 写入文本
p.write_bytes(b"hello")             # 写入字节

# 目录操作
p.mkdir(parents=True, exist_ok=True)  # 创建目录
list(p.iterdir())                      # 列出目录内容
list(p.glob("*.py"))                   # 匹配文件
list(p.rglob("*.txt"))                 # 递归匹配

# 路径转换
p.resolve()     # 绝对路径(解析符号链接)
p.absolute()    # 绝对路径(不解析符号链接)
p.relative_to(Path("/home"))  # 相对路径

十一、类型标注(typing)

11.1 基础标注

# Python 3.9+ 可以直接用小写内置类型
def greet(name: str) -> str:
    return f"Hello, {name}"

def process(items: list[int]) -> dict[str, int]:
    pass

def get_coords() -> tuple[float, float]:
    return (1.0, 2.0)

def get_tags() -> set[str]:
    return {"python", "ai"}

11.2 Optional 与 Union

# 可选值(可以是 None)
def find_user(id: int) -> User | None:  # Python 3.10+ 语法
    pass

# 等价写法
from typing import Optional, Union
def find_user(id: int) -> Optional[User]:  # 传统写法
    pass
def find_user(id: int) -> Union[User, None]:  # 更明确的写法
    pass

# 多种类型
def process(value: int | str | float) -> str:  # Python 3.10+
    pass
def process(value: Union[int, str, float]) -> str:  # 传统写法
    pass

11.3 高级类型

from typing import (
    Literal,        # 字面量类型
    TypedDict,      # 字典结构类型
    Callable,       # 可调用类型
    TypeAlias,      # 类型别名
    Any,            # 任意类型(尽量避免)
    Never,          # 永不返回(Python 3.11+)
    Self,           # 当前类类型(Python 3.11+)
    TypeGuard,      # 类型守卫(Python 3.10+)
    Protocol,       # 结构化子类型(鸭子类型)
    overload,       # 函数重载
)

# Literal:限定具体值
def set_mode(mode: Literal["read", "write", "append"]) -> None:
    pass

# TypedDict:定义字典结构
class UserInfo(TypedDict):
    name: str
    age: int
    email: str  # 必填

class UserInfoOptional(TypedDict, total=False):
    name: str
    age: int
    email: str  # 全部可选

# Callable:函数类型
def apply(func: Callable[[int, int], int], a: int, b: int) -> int:
    return func(a, b)

# 类型别名(Python 3.12+ 新语法)
type Vector = list[float]
type Matrix = list[Vector]
type JsonValue = str | int | float | bool | None | list["JsonValue"] | dict[str, "JsonValue"]

# Protocol:结构化子类型(不需要继承)
from typing import Protocol

class Drawable(Protocol):
    def draw(self) -> None: ...

class Circle:
    def draw(self) -> None:
        print("Drawing circle")

def render(obj: Drawable):  # Circle 自动满足 Drawable 协议
    obj.draw()

# @overload:函数重载(给类型检查器看的,运行时不生效)
from typing import overload

@overload
def process(x: int) -> int: ...
@overload
def process(x: str) -> str: ...
def process(x: int | str) -> int | str:
    if isinstance(x, int):
        return x * 2
    return x.upper()

11.4 泛型(Python 3.12+ 新语法)

# Python 3.12+ 新语法(PEP 695)
class Stack[T]:
    def __init__(self) -> None:
        self._items: list[T] = []
    
    def push(self, item: T) -> None:
        self._items.append(item)
    
    def pop(self) -> T:
        return self._items.pop()

def first[T](items: list[T]) -> T:
    return items[0]

# 带约束的类型参数
def max_val[T: (int, float)](a: T, b: T) -> T:
    return a if a > b else b

# 类型别名也可以是泛型(Python 3.12+)
type Pair[T] = tuple[T, T]
type Result[T, E] = tuple[T | None, E | None]

十二、生成器(Generator)

12.1 生成器函数

# 用 yield 定义生成器函数
def count_up(max_val: int):
    n = 0
    while n < max_val:
        yield n
        n += 1

# 使用
for num in count_up(5):
    print(num)  # 0, 1, 2, 3, 4

# 生成器是惰性求值的,不会一次性创建所有值
gen = count_up(1000000)  # 几乎不占内存
next(gen)  # 0
next(gen)  # 1

12.2 yield from(委托生成器)

def flatten(nested_list):
    for item in nested_list:
        if isinstance(item, list):
            yield from flatten(item)  # 委托给子生成器
        else:
            yield item

list(flatten([1, [2, 3], [4, [5, 6]]]))  # [1, 2, 3, 4, 5, 6]

12.3 生成器表达式

# 圆括号创建生成器表达式(惰性求值)
squares = (x**2 for x in range(1000000))  # 不占内存
sum(x**2 for x in range(1000000))         # 直接传给函数时不需要额外括号

12.4 send() 与生成器双向通信

def accumulator():
    total = 0
    while True:
        value = yield total  # 产出 total,接收外部 send 的值
        if value is None:
            break
        total += value

acc = accumulator()
next(acc)          # 启动生成器,运行到第一个 yield,返回 0
acc.send(10)       # 发送 10,返回 10
acc.send(20)       # 发送 20,返回 30
acc.send(5)        # 发送 5,返回 35
acc.send(None)     # 结束生成器

十三、装饰器(Decorator)

13.1 基础装饰器

import functools
import time

def timer(func):
    """计算函数执行时间的装饰器。"""
    @functools.wraps(func)  # 保留原函数的 __name__ 和 __doc__
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        elapsed = time.perf_counter() - start
        print(f"{func.__name__} took {elapsed:.4f}s")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)
    return "done"

slow_function()  # "slow_function took 1.0012s"

13.2 带参数的装饰器

def retry(max_attempts: int = 3, delay: float = 1.0):
    """失败重试装饰器。"""
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(1, max_attempts + 1):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if attempt == max_attempts:
                        raise
                    print(f"Attempt {attempt} failed: {e}, retrying...")
                    time.sleep(delay)
        return wrapper
    return decorator

@retry(max_attempts=5, delay=0.5)
def fetch_data(url: str):
    pass

13.3 类装饰器

class CountCalls:
    """记录函数被调用次数的类装饰器。"""
    def __init__(self, func):
        self.func = func
        self.count = 0
        functools.update_wrapper(self, func)
    
    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"Call {self.count} of {self.func.__name__}")
        return self.func(*args, **kwargs)

@CountCalls
def say_hello():
    print("Hello!")

say_hello()  # Call 1 of say_hello / Hello!
say_hello()  # Call 2 of say_hello / Hello!

13.4 多个装饰器叠加

# 装饰器从下到上应用(最靠近函数的先应用)
@decorator_a
@decorator_b
@decorator_c
def func():
    pass

# 等价于:func = decorator_a(decorator_b(decorator_c(func)))

十四、上下文管理器(Context Manager)

14.1 with 语句

# 文件操作(自动关闭)
with open("file.txt", "r") as f:
    content = f.read()

# 多个上下文管理器
with open("in.txt") as fin, open("out.txt", "w") as fout:
    fout.write(fin.read())

# Python 3.10+:带括号的上下文管理器(可多行)
with (
    open("in.txt") as fin,
    open("out.txt", "w") as fout,
):
    fout.write(fin.read())

14.2 自定义上下文管理器(类方式)

class DatabaseConnection:
    def __init__(self, connection_string: str):
        self.connection_string = connection_string
        self.connection = None
    
    def __enter__(self):
        print("Connecting to database...")
        self.connection = f"conn:{self.connection_string}"
        return self.connection  # 赋值给 as 后面的变量
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Closing connection...")
        self.connection = None
        # 返回 True 会抑制异常,返回 False 或 None 会传播异常
        return False

with DatabaseConnection("postgres://localhost/mydb") as conn:
    print(f"Using {conn}")
# 退出 with 块时自动调用 __exit__

14.3 自定义上下文管理器(生成器方式)

from contextlib import contextmanager

@contextmanager
def temporary_directory():
    """创建临时目录,退出时自动删除。"""
    import tempfile, shutil
    tmpdir = tempfile.mkdtemp()
    try:
        yield tmpdir  # yield 的值赋值给 as 后面的变量
    finally:
        shutil.rmtree(tmpdir)  # 无论如何都会清理

with temporary_directory() as tmpdir:
    print(f"Working in {tmpdir}")
# 退出 with 块时自动删除临时目录

十五、迭代器协议

# 可迭代对象:实现了 __iter__() 方法
# 迭代器:实现了 __iter__() 和 __next__() 方法

class CountDown:
    """倒计时迭代器。"""
    def __init__(self, start: int):
        self.current = start
    
    def __iter__(self):
        return self  # 迭代器返回自身
    
    def __next__(self):
        if self.current <= 0:
            raise StopIteration
        self.current -= 1
        return self.current + 1

for num in CountDown(5):
    print(num)  # 5, 4, 3, 2, 1

# iter() 和 next()
nums = [1, 2, 3]
it = iter(nums)    # 获取迭代器
next(it)           # 1
next(it)           # 2
next(it)           # 3
next(it)           # ❌ StopIteration
next(it, "done")   # "done"(提供默认值不抛异常)

十六、模式匹配(match-case,Python 3.10+)

# 基础匹配
def handle_status(status_code: int) -> str:
    match status_code:
        case 200:
            return "OK"
        case 404:
            return "Not Found"
        case 500 | 502 | 503:    # 多个值
            return "Server Error"
        case _:                   # 通配符(类似 default)
            return "Unknown"

# 解构匹配
def process_command(command: str):
    match command.split():
        case ["quit"]:
            print("Goodbye!")
        case ["go", direction]:
            print(f"Going {direction}")
        case ["go", direction, speed]:
            print(f"Going {direction} at {speed}")
        case _:
            print("Unknown command")

# 匹配字典
def handle_event(event: dict):
    match event:
        case {"type": "click", "x": x, "y": y}:
            print(f"Click at ({x}, {y})")
        case {"type": "keypress", "key": key}:
            print(f"Key pressed: {key}")
        case {"type": "resize", "width": w, "height": h} if w > 1000:
            print(f"Large resize: {w}x{h}")  # 守卫条件
        case _:
            print("Unknown event")

# 匹配类实例
from dataclasses import dataclass

@dataclass
class Point:
    x: float
    y: float

def describe_point(point: Point):
    match point:
        case Point(0, 0):
            return "Origin"
        case Point(0, y):
            return f"On Y-axis at {y}"
        case Point(x, 0):
            return f"On X-axis at {x}"
        case Point(x, y) if x == y:
            return f"On diagonal at ({x}, {y})"
        case Point(x, y):
            return f"Point at ({x}, {y})"

# 捕获子模式(Python 3.10+)
match response:
    case {"status": 200, "body": body} as full_response:
        print(f"Success: {body}")
        print(f"Full: {full_response}")

十七、正则表达式(re 模块)

import re

text = "Contact us at support@example.com or sales@test.org"

# 搜索
match = re.search(r'[\w.]+@[\w.]+', text)
if match:
    print(match.group())   # "support@example.com"
    print(match.start())   # 起始位置
    print(match.end())     # 结束位置
    print(match.span())    # (起始, 结束)

# 查找所有
emails = re.findall(r'[\w.]+@[\w.]+', text)
# ["support@example.com", "sales@test.org"]

# 替换
result = re.sub(r'\d+', 'NUM', "Order 123 has 45 items")
# "Order NUM has NUM items"

# 分割
parts = re.split(r'[;,\s]+', "a, b; c  d")
# ["a", "b", "c", "d"]

# 编译正则(重复使用时性能更好)
email_pattern = re.compile(r'[\w.]+@[\w.]+.[\w]+')
matches = email_pattern.findall(text)

# 命名分组
pattern = re.compile(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})')
m = pattern.match("2024-01-15")
m.group("year")   # "2024"
m.group("month")  # "01"
m.groupdict()     # {"year": "2024", "month": "01", "day": "15"}

# 常用标志
re.IGNORECASE   # 忽略大小写
re.MULTILINE    # ^ 和 $ 匹配每行
re.DOTALL       # . 匹配换行符
re.VERBOSE      # 允许注释和空白

# 常用模式速查
# \d  数字      \D  非数字
# \w  字母数字  \W  非字母数字
# \s  空白      \S  非空白
# .   任意字符(除换行)
# ^   行首      $   行尾
# *   0次或多次  +   1次或多次
# ?   0次或1次  {n} 恰好n次
# {n,m} n到m次  (?:...) 非捕获组

十八、日期与时间

from datetime import datetime, date, time, timedelta
from zoneinfo import ZoneInfo  # Python 3.9+

# 当前时间
now = datetime.now()                    # 本地时间
utc_now = datetime.now(ZoneInfo("UTC")) # UTC 时间
today = date.today()                    # 今天日期

# 创建
dt = datetime(2024, 1, 15, 10, 30, 0)
d = date(2024, 1, 15)
t = time(10, 30, 0)

# 格式化
dt.strftime("%Y-%m-%d %H:%M:%S")       # "2024-01-15 10:30:00"
dt.strftime("%Y年%m月%d日 %H:%M")       # "2024年01月15日 10:30"

# 解析
datetime.strptime("2024-01-15 10:30:00", "%Y-%m-%d %H:%M:%S")

# 时间差
delta = timedelta(days=7, hours=3)
future = now + delta
past = now - timedelta(weeks=2)
diff = dt1 - dt2  # 返回 timedelta

# 时区
beijing_time = datetime.now(ZoneInfo("Asia/Shanghai"))
tokyo_time = beijing_time.astimezone(ZoneInfo("Asia/Tokyo"))

# 时间戳
timestamp = datetime.now().timestamp()          # float
dt = datetime.fromtimestamp(1705276800)         # 时间戳 → datetime
dt = datetime.fromtimestamp(1705276800, tz=ZoneInfo("UTC"))

十九、常用标准库速查

模块用途常用功能
os操作系统交互os.environos.path(推荐用 pathlib 替代)
sys解释器相关sys.argv(命令行参数)、sys.pathsys.exit()
jsonJSON 编解码json.dumps()json.loads()json.dump()json.load()
re正则表达式re.search()re.findall()re.sub()
datetime日期时间datetime.now()timedeltastrftime/strptime
collections高级数据结构defaultdictCounterdequeOrderedDictnamedtuple
itertools迭代器工具chainproductcombinationspermutationsgroupby
functools函数工具lru_cachepartialreducewraps
pathlib路径操作Path(推荐替代 os.path)
typing类型标注OptionalUnionLiteralTypedDictProtocol
dataclasses数据类@dataclass
enum枚举EnumIntEnumFlag
logging日志logging.getLogger()basicConfig()
unittest单元测试TestCaseassertEqual
math数学函数ceilfloorsqrtloggcd
random随机数random()randint()choice()shuffle()
hashlib哈希md5()sha256()
uuidUUIDuuid4()(随机)、uuid1()(基于时间)
copy复制copy.copy()(浅拷贝)、copy.deepcopy()(深拷贝)
abc抽象基类ABCabstractmethod
contextlib上下文管理器contextmanagersuppressredirect_stdout
textwrap文本包装dedent()wrap()fill()

二十、异步编程基础(asyncio)

import asyncio

# 定义协程
async def fetch_data(url: str) -> dict:
    await asyncio.sleep(1)  # 模拟网络请求
    return {"url": url, "status": 200}

# 运行协程(程序入口)
async def main():
    # 等待单个协程
    result = await fetch_data("https://api.example.com")
    
    # 并发执行多个协程
    results = await asyncio.gather(
        fetch_data("https://api1.example.com"),
        fetch_data("https://api2.example.com"),
        fetch_data("https://api3.example.com"),
    )
    
    # 创建后台任务(不立即等待)
    task = asyncio.create_task(fetch_data("https://api.example.com"))
    # ... 做其他事 ...
    result = await task  # 需要时再等待
    
    # 带超时的等待
    try:
        result = await asyncio.wait_for(fetch_data("..."), timeout=5.0)
    except asyncio.TimeoutError:
        print("请求超时")
    
    # 限制并发数
    semaphore = asyncio.Semaphore(3)  # 最多3个并发
    async def limited_fetch(url):
        async with semaphore:
            return await fetch_data(url)
    
    await asyncio.gather(*[limited_fetch(f"url_{i}") for i in range(10)])

# 启动
asyncio.run(main())

以上就是 Python 基础语法的完整汇总。覆盖了从变量、数据类型到异步编程的所有核心知识点,并标注了各版本引入的新语法。