让代码更优雅、更Pythonic的语法特性详解
用简洁的语法创建列表,替代传统的for循环
# 传统方式 squares = [] for i in range(10): squares.append(i ** 2) # 语法糖方式(列表推导式) squares = [i ** 2 for i in range(10)] # 带条件的列表推导式 even_squares = [i ** 2 for i in range(10) if i % 2 == 0]
# 创建一个5x5的矩阵 matrix = [[i * 5 + j for j in range(5)] for i in range(5)] # 展平嵌套列表 nested = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] flattened = [num for sublist in nested for num in sublist]
快速创建和操作字典的优雅方式
# 创建平方数字典 squares_dict = {i: i ** 2 for i in range(5)} # 结果: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} # 交换字典的键和值 original = {'a': 1, 'b': 2, 'c': 3} swapped = {value: key for key, value in original.items()} # 过滤字典 scores = {'Alice': 85, 'Bob': 92, 'Charlie': 78} high_scores = {name: score for name, score in scores.items() if score >= 90}
创建集合的简洁语法,自动去重
# 从列表创建集合(自动去重) numbers = [1, 2, 2, 3, 3, 4, 5] unique_squares = {i ** 2 for i in numbers} # 结果: {1, 4, 9, 16, 25} # 提取字符串中的所有唯一字符 text = "hello world" unique_chars = {char for char in text if char != ' '}
* 和 ** 运算符的妙用
# 列表/元组解包 first, *middle, last = [1, 2, 3, 4, 5] # first = 1, middle = [2, 3, 4], last = 5 # 合并列表 list1 = [1, 2, 3] list2 = [4, 5, 6] merged = [*list1, *list2] # 结果: [1, 2, 3, 4, 5, 6] # 字典解包 dict1 = {'a': 1, 'b': 2} dict2 = {'c': 3, 'd': 4} merged_dict = {**dict1, **dict2} # 函数参数解包 def add(a, b, c): return a + b + c args = [1, 2, 3] result = add(*args) # 解包列表作为位置参数 kwargs = {'a': 1, 'b': 2, 'c': 3} result = add(**kwargs) # 解包字典作为关键字参数
强大的序列切片功能
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 基本切片 numbers[2:5] # [2, 3, 4] numbers[:3] # [0, 1, 2] numbers[7:] # [7, 8, 9] numbers[::2] # [0, 2, 4, 6, 8] 步长为2 numbers[::-1] # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 反转 # 切片赋值 numbers[2:5] = [20, 30, 40] # 替换切片部分 numbers[::2] = [0, 0, 0, 0, 0] # 间隔赋值 # 浅拷贝 copy_of_numbers = numbers[:]
Python 3.6+ 引入的强大字符串格式化方式
name = "Alice" age = 30 # 基本用法 greeting = f"Hello, {name}! You are {age} years old." # 表达式 result = f"2 + 3 = {2 + 3}" # 调用方法 text = "hello" formatted = f"{text.upper()} world!" # 格式化数字 pi = 3.1415926 formatted_pi = f"π = {pi:.2f}" # π = 3.14 # 日期格式化 from datetime import datetime now = datetime.now() formatted_date = f"Today is {now:%Y-%m-%d %H:%M:%S}" # 调试模式 (Python 3.8+) x = 10 debug = f"{x = }" # 'x = 10'
Python 3.8+ 引入的 := 运算符,在表达式中同时进行赋值和返回
# 传统方式 data = get_data() if data: process(data) # 使用海象运算符 if (data := get_data()): process(data) # 在列表推导式中使用 # 过滤出长度大于5且转换为大写后的字符串 words = ["hello", "world", "python", "code"] result = [upper for word in words if len(upper := word.upper()) > 5] # 在while循环中使用 while (chunk := file.read(1024)): process(chunk)
连续比较操作的优雅写法
# 传统方式 if x > 0 and x < 10: pass # 链式比较(更Pythonic) if 0 < x < 10: pass # 更多例子 if 0 <= score <= 100: print("Valid score") # 检查是否在所有边界内 if 1 < x <= 5 < y <= 10: pass
简洁的条件赋值
# 传统方式 if condition: x = 'true' else: x = 'false' # 三元表达式 x = 'true' if condition else 'false' # 实际应用 age = 20 status = "成年" if age >= 18 else "未成年" # 嵌套三元表达式(谨慎使用,可读性下降) grade = "优秀" if score >= 90 else "良好" if score >= 80 else "及格" if score >= 60 else "不及格"
自定义类的运算符行为
class Vector: def __init__(self, x, y): self.x = x self.y = y # 重载 + 运算符 def __add__(self, other): return Vector(self.x + other.x, self.y + other.y) # 重载 * 运算符(标量乘法) def __mul__(self, scalar): return Vector(self.x * scalar, self.y * scalar) # 重载字符串表示 def __str__(self): return f"Vector({self.x}, {self.y})" # 重载比较运算符 def __eq__(self, other): return self.x == other.x and self.y == other.y # 使用 v1 = Vector(1, 2) v2 = Vector(3, 4) v3 = v1 + v2 # 调用 __add__ v4 = v1 * 3 # 调用 __mul__ print(v3) # Vector(4, 6)
在不修改原函数的情况下增强函数功能
# 基本装饰器 def my_decorator(func): def wrapper(): print("Before function call") func() print("After function call") return wrapper @my_decorator def say_hello(): print("Hello!") # 带参数的装饰器 def repeat(times): def decorator(func): def wrapper(*args, **kwargs): for _ in range(times): result = func(*args, **kwargs) return result return wrapper return decorator @repeat(times=3) def greet(name): print(f"Hello, {name}!") # 类装饰器 class CountCalls: def __init__(self, func): self.func = func self.count = 0 def __call__(self, *args, **kwargs): self.count += 1 print(f"Call count: {self.count}") return self.func(*args, **kwargs) @CountCalls def say_hi(): print("Hi!")
自动管理资源,确保清理操作执行
# 传统方式 file = open('file.txt', 'r') try: data = file.read() finally: file.close() # 使用 with 语句(语法糖) with open('file.txt', 'r') as file: data = file.read() # 自动关闭文件 # 自定义上下文管理器 class MyContext: def __enter__(self): print("Entering context") return self def __exit__(self, exc_type, exc_val, exc_tb): print("Exiting context") return False # 不抑制异常 with MyContext() as ctx: print("Inside context") # 使用 contextlib(更简洁) from contextlib import contextmanager @contextmanager def my_context(): print("Entering") yield "resource" print("Exiting") with my_context() as resource: print(f"Using {resource}")
惰性计算,节省内存的迭代器
# 生成器函数 def count_up_to(n): i = 0 while i < n: yield i i += 1 # 使用生成器 for num in count_up_to(5): print(num) # 0, 1, 2, 3, 4 # 生成器表达式(类似列表推导式,但使用圆括号) squares = (i ** 2 for i in range(10)) print(next(squares)) # 0 print(next(squares)) # 1 # 内存对比 # 列表:立即在内存中创建所有元素 list_comp = [i ** 2 for i in range(1000000)] # 占用大量内存 # 生成器:按需生成,几乎不占内存 gen_exp = (i ** 2 for i in range(1000000)) # 占用极少内存 # yield from 语法 (Python 3.3+) def sub_gen(): yield 1 yield 2 yield 3 def main_gen(): yield "start" yield from sub_gen() # 委托给子生成器 yield "end"
创建小型匿名函数的简洁方式
# 传统函数 def add(x, y): return x + y # Lambda表达式 add = lambda x, y: x + y # 在高阶函数中使用 numbers = [1, 2, 3, 4, 5] squared = list(map(lambda x: x ** 2, numbers)) filtered = list(filter(lambda x: x % 2 == 0, numbers)) sorted_by_abs = sorted([-3, 1, -2, 5], key=lambda x: abs(x)) # 配合三元表达式 max_value = lambda a, b: a if a > b else b # 闭包示例 def make_multiplier(n): return lambda x: x * n double = make_multiplier(2) triple = make_multiplier(3) print(double(5)) # 10 print(triple(5)) # 15
循环正常完成后执行else块(未被break中断)
# for-else 示例 numbers = [1, 2, 3, 4, 5] for num in numbers: if num == 0: print("Found zero!") break else: print("No zero found in the list") # 这行会执行 # 实际应用:查找质数 def is_prime(n): if n < 2: return False for i in range(2, int(n ** 0.5) + 1): if n % i == 0: return False return True # 使用 for-else 查找质数 for n in range(2, 20): for i in range(2, int(n ** 0.5) + 1): if n % i == 0: break else: print(f"{n} is prime")
利用and和or的短路特性
# 短路求值 # and: 如果第一个为False,不评估第二个 # or: 如果第一个为True,不评估第二个 # 安全访问嵌套字典 data = {'user': {'name': 'Alice'}} name = data.get('user') and data['user'].get('name') # 默认值模式(类似其他语言的 ?? 或 ||) # 注意:这只在左侧为False时有效 username = provided_name or "Guest" # 更安全的默认值(使用海象运算符或条件表达式) username = provided_name if provided_name is not None else "Guest" # 函数调用中的短路 condition and do_something() # 只有condition为True时才调用 condition or do_fallback() # 只有condition为False时才调用
使用切片进行批量操作和修改
numbers = [1, 2, 3, 4, 5] # 切片赋值 numbers[1:3] = [20, 30] # [1, 20, 30, 4, 5] numbers[:2] = [10, 20, 30] # 可改变长度 [10, 20, 30, 30, 4, 5] # 插入元素(不删除) numbers[2:2] = [99, 99] # 在索引2处插入 # 删除切片 numbers[1:3] = [] # 删除索引1和2的元素 del numbers[::2] # 删除所有偶数索引的元素 # 替换所有元素 numbers[:] = [1, 2, 3] # 修改原列表,而不是创建新列表
Python 3.5+ 引入的异步编程语法
import asyncio # 异步函数 async def fetch_data(url): print(f"Fetching {url}...") await asyncio.sleep(1) # 模拟IO操作 return f"Data from {url}" # 并发执行多个异步任务 async def main(): # 顺序执行 result1 = await fetch_data("url1") result2 = await fetch_data("url2") # 并发执行 results = await asyncio.gather( fetch_data("url1"), fetch_data("url2"), fetch_data("url3") ) return results # 运行异步函数 asyncio.run(main()) # 异步上下文管理器 (Python 3.7+) class AsyncContext: async def __aenter__(self): print("Entering async context") return self async def __aexit__(self, exc_type, exc, tb): print("Exiting async context") async def use_async_context(): async with AsyncContext() as ctx: print("Inside async context")
Python 3.5+ 的类型注解语法
from typing import List, Dict, Optional, Tuple, Union # 基本类型提示 def greet(name: str, age: int) -> str: return f"Hello {name}, you are {age} years old" # 复杂类型 def process_data( items: List[int], mapping: Dict[str, int], optional_value: Optional[float] = None ) -> Tuple[int, str]: pass # Union类型 (Python 3.10+ 可以用 X | Y) def handle_id(id: Union[int, str]) -> str: return str(id) # Python 3.10+ 的新语法 def handle_id_new(id: int | str) -> str: return str(id) # 类型别名 Vector = List[float] def scale(vector: Vector, scalar: float) -> Vector: return [x * scalar for x in vector] # 泛型 (Python 3.9+) from typing import TypeVar, Generic T = TypeVar('T') class Stack(Generic[T]): def __init__(self): self._items: List[T] = [] def push(self, item: T) -> None: self._items.append(item) def pop(self) -> T: return self._items.pop()
Python 3.10+ 引入的match-case语法,类似其他语言的switch-case但更强大
# 基本匹配 def http_status(status: int) -> str: match status: case 200: return "OK" case 404: return "Not Found" case 500: return "Internal Server Error" case _: return "Unknown Status" # 解构匹配 point = (3, 5) match point: case (0, 0): print("Origin") case (0, y): print(f"On Y axis at {y}") case (x, 0): print(f"On X axis at {x}") case (x, y): print(f"Point at ({x}, {y})") # 带条件的匹配(守护条件) match point: case (x, y) if x == y: print("On diagonal") case (x, y): print(f"Point ({x}, {y})") # 匹配对象属性 class Point: def __init__(self, x, y): self.x = x self.y = y p = Point(3, 4) match p: case Point(x=0, y=0): print("Origin") case Point(x=0, y=y): print(f"On Y axis at {y}") case Point(x=x, y=y): print(f"Point at ({x}, {y})")
在更多场景中使用海象运算符简化代码
# 在while循环中使用 while (chunk := file.read(1024)) != "": process(chunk) # 在列表推导式中使用 # 过滤出长度大于5且大写的字符串 words = ["hello", "world", "python", "code"] result = [upper for word in words if len(upper := word.upper()) > 5] # 在推导式中避免重复计算 # 传统方式(计算两次) squares = [x**2 for x in range(10) if x**2 > 25] # 使用海象运算符(计算一次) squares = [sq for x in range(10) if (sq := x**2) > 25] # 在条件表达式中使用 def process(data): if (result := expensive_computation(data)) is not None: return result return fallback()
Python灵活的模块导入语法
# 基本导入 import os import sys, os # 同时导入多个(不推荐) # 从模块导入特定对象 from math import sqrt, pi from datetime import datetime as dt # 使用别名 # 导入所有(不推荐在生产代码中使用) from math import * # 导入所有公开对象 # 相对导入(在包内使用) from . import sibling_module from ..parent import module # 条件导入 try: import numpy as np except ImportError: np = None # 动态导入 (Python 3.7+) import importlib module = importlib.import_module('math') # __all__ 控制导出 # 在 module.py 中定义: # __all__ = ['public_func1', 'public_func2'] # 只有列出的名称会被 `from module import *` 导入 # if __name__ == "__main__" 惯用法 if __name__ == "__main__": # 只有直接运行此文件时才会执行 main()
dict.get(), setdefault(), update() 等方法让字典操作更安全、更简洁
# get() - 安全获取值,避免KeyError data = {'a': 1, 'b': 2} # 传统方式(容易抛出KeyError) try: value = data['c'] except KeyError: value = 'default' # 使用get()(语法糖) value = data.get('c', 'default') # 'default' # setdefault() - 如果键不存在,设置默认值 # 传统方式 if 'key' not in data: data['key'] = [] data['key'].append(1) # 使用setdefault()(更简洁) data.setdefault('key', []).append(1) # update() - 批量更新 data.update({'c': 3, 'd': 4}) data.update(e=5, f=6) # 关键字参数形式 # defaultdict - 自动初始化默认值 from collections import defaultdict dd = defaultdict(list) # 访问不存在的键时,自动创建空列表 dd['new_key'].append(1) # 不需要先检查或初始化 dd_int = defaultdict(int) # 默认值为0 dd_int['count'] += 1 # 直接累加 # dict() 构造函数技巧 # 从键值对列表创建 pairs = [('a', 1), ('b', 2)] dict(pairs) # {'a': 1, 'b': 2} # 从两个列表创建 keys = ['a', 'b', 'c'] values = [1, 2, 3] dict(zip(keys, values)) # {'a': 1, 'b': 2, 'c': 3} # 合并字典 (Python 3.9+) dict1 = {'a': 1, 'b': 2} dict2 = {'c': 3, 'd': 4} merged = dict1 | dict2 # 使用 | 运算符 (Python 3.9+) dict1 |= dict2 # 原地合并 (Python 3.9+)
集合的操作符重载,让集合运算更直观
# 创建集合 set1 = {1, 2, 3, 4} set2 = {3, 4, 5, 6} # 并集 (Union) - 使用 | 运算符 union = set1 | set2 # {1, 2, 3, 4, 5, 6} union_method = set1.union(set2) # 等价方法 # 交集 (Intersection) - 使用 & 运算符 intersection = set1 & set2 # {3, 4} intersection_method = set1.intersection(set2) # 差集 (Difference) - 使用 - 运算符 difference = set1 - set2 # {1, 2} (在set1但不在set2中) difference_method = set1.difference(set2) # 对称差集 (Symmetric Difference) - 使用 ^ 运算符 symmetric_diff = set1 ^ set2 # {1, 2, 5, 6} (只在一个集合中) sym_diff_method = set1.symmetric_difference(set2) # 原地操作 set1 |= set2 # 原地并集 set1 &= set2 # 原地交集 set1 -= set2 # 原地差集 set1 ^= set2 # 原地对称差集 # 子集和超集判断 small = {1, 2} large = {1, 2, 3, 4} small <= large # True (子集) large >= small # True (超集) small < large # True (真子集) # 成员检测(比列表快得多) if 3 in set1: # O(1) 平均时间复杂度 print("Found!") # 集合推导式(之前已介绍) squared_set = {x**2 for x in range(10)}
Python中优雅的赋值语法
# 多重赋值(解包赋值) a, b = 1, 2 # 等价于: # a = 1 # b = 2 # 交换变量(不需要临时变量!) a, b = b, a # 经典语法糖 # 链式赋值 a = b = c = 0 # 三个变量都赋值为0 # 注意:对于可变对象要小心! list1 = list2 = [] # 两个变量引用同一个列表! list1.append(1) print(list2) # [1] - 意想不到的结果 # 增量赋值运算符 x = 10 x += 5 # x = x + 5 x -= 3 # x = x - 3 x *= 2 # x = x * 2 x /= 4 # x = x / 4 x //= 2 # x = x // 2 (整除) x **= 3 # x = x ** 3 (幂运算) x %= 3 # x = x % 3 (取模) # 对于列表 lst = [1, 2, 3] lst += [4, 5] # 等价于 lst.extend([4, 5]) lst *= 2 # [1, 2, 3, 1, 2, 3] # 解包赋值的高级用法 (a, b), (c, d) = (1, 2), (3, 4) # a=1, b=2, c=3, d=4 head, *tail = [1, 2, 3, 4, 5] # head=1, tail=[2, 3, 4, 5]
让循环和迭代更Pythonic的内置函数
# enumerate() - 同时获取索引和值 fruits = ['apple', 'banana', 'cherry'] # 传统方式 for i in range(len(fruits)): print(i, fruits[i]) # 使用enumerate()(更优雅) for i, fruit in enumerate(fruits): print(i, fruit) # 指定起始索引 for i, fruit in enumerate(fruits, start=1): print(i, fruit) # 从1开始计数 # zip() - 并行迭代多个序列 names = ['Alice', 'Bob', 'Charlie'] scores = [85, 92, 78] for name, score in zip(names, scores): print(f"{name}: {score}") # zip() 的不等长处理 from itertools import zip_longest for item in zip_longest([1, 2, 3], ['a', 'b'], fillvalue='default'): print(item) # (1, 'a'), (2, 'b'), (3, 'default') # sorted() - 排序(返回新列表,不修改原列表) numbers = [3, 1, 4, 1, 5, 9, 2] sorted_numbers = sorted(numbers) # [1, 1, 2, 3, 4, 5, 9] sorted_desc = sorted(numbers, reverse=True) # 降序 # 按自定义键排序 students = [ {'name': 'Alice', 'score': 85}, {'name': 'Bob', 'score': 92}, {'name': 'Charlie', 'score': 78} ] sorted_by_score = sorted(students, key=lambda x: x['score']) # reversed() - 反转序列 for num in reversed([1, 2, 3, 4, 5]): print(num) # 5, 4, 3, 2, 1 # 组合使用 data = [(1, 'b'), (3, 'a'), (2, 'c')] # 先按第二个元素排序,再按第一个元素排序 sorted_data = sorted(data, key=lambda x: (x[1], x[0]))
将方法变为属性访问,实现getter/setter的优雅语法
# 传统getter/setter class Temperature: def __init__(self, celsius=0): self._celsius = celsius def get_celsius(self): return self._celsius def set_celsius(self, value): if value < -273.15: self._celsius = value else: raise ValueError("Temperature below absolute zero!") # 使用 @property (语法糖) class Temperature: def __init__(self, celsius=0): self._celsius = celsius @property def celsius(self): """Getter""" return self._celsius @celsius.setter def celsius(self, value): """Setter""" if value < -273.15: self._celsius = value else: raise ValueError("Temperature below absolute zero!") @property def fahrenheit(self): """只读属性""" return self._celsius * 9/5 + 32 # 使用(像访问属性一样,但实际上调用了方法) temp = Temperature(25) print(temp.celsius) # 调用getter temp.celsius = 30 # 调用setter print(temp.fahrenheit) # 调用getter(只读) # @staticmethod 和 @classmethod class MathUtils: @staticmethod def add(a, b): """静态方法:不需要self或cls""" return a + b @classmethod def from_string(cls, s): """类方法:第一个参数是类本身""" a, b = map(int, s.split(',')) return cls(a, b) def __init__(self, a, b): self.a = a self.b = b # 使用 result = MathUtils.add(1, 2) # 不需要实例化 instance = MathUtils.from_string("3,4") # 工厂方法
自动生成__init__、__repr__等方法的语法糖
# 传统类定义 class Point: def __init__(self, x, y): self.x = x self.y = y def __repr__(self): return f"Point({self.x}, {self.y})" def __eq__(self, other): return self.x == other.x and self.y == other.y # 使用 @dataclass (Python 3.7+) from dataclasses import dataclass @dataclass class Point: x: float y: float # 自动生成 __init__, __repr__, __eq__ 等方法 p1 = Point(1, 2) p2 = Point(1, 2) print(p1) # Point(x=1, y=2) print(p1 == p2) # True # dataclass的高级用法 @dataclass class User: name: str email: str age: int = 0 # 默认值 active: bool = True def greet(self): return f"Hello, {self.name}!" # namedtuple - 轻量级不可变数据类 from collections import namedtuple Point = namedtuple('Point', ['x', 'y'']) p = Point(1, 2) print(p.x, p.y) # 1 2 # p.x = 3 # 错误!namedtuple是不可变的 # namedtuple的现代替代:typing.NamedTuple from typing import NamedTuple class Point(NamedTuple): x: float y: float def distance_from_origin(self): return (self.x ** 2 + self.y ** 2) ** 0.5
函数式编程工具和性能优化装饰器
from functools import lru_cache, partial, reduce # @lru_cache - 自动缓存函数结果(记忆化) # 非常适合递归函数,如斐波那契数列 @lru_cache(maxsize=128) def fibonacci(n): if n < 2: return n return fibonacci(n-1) + fibonacci(n-2) print(fibonacci(100)) # 非常快,因为使用了缓存 # partial - 固定部分参数,创建新函数 def power(base, exponent): return base ** exponent square = partial(power, exponent=2) cube = partial(power, exponent=3) print(square(5)) # 25 print(cube(5)) # 125 # reduce - 累积计算(Python 3中移至functools) from functools import reduce # 计算阶乘 factorial = reduce(lambda x, y: x * y, range(1, 6)) # 120 # 等价于 result = 1 for i in range(1, 6): result *= i # @wraps - 保留被装饰函数的元数据 from functools import wraps def my_decorator(func): @wraps(func) # 保留原函数的名称、文档字符串等 def wrapper(*args, **kwargs): """Wrapper function""" print("Before") result = func(*args, **kwargs) print("After") return result return wrapper @my_decorator def greet(name): """Greet someone""" print(f"Hello, {name}!") print(greet.__name__) # 'greet' (而不是 'wrapper') print(greet.__doc__) """Greet someone"""
通过固定属性来大幅减少内存使用
# 普通类 - 使用 __dict__ 存储属性(内存开销大) class NormalUser: def __init__(self, name, age): self.name = name self.age = age user1 = NormalUser("Alice", 30) user1.new_attr = "dynamic" # 可以动态添加属性 # 使用 __slots__ - 禁止动态属性,节省内存 class OptimizedUser: __slots__ = ('name', 'age') # 只允许这两个属性 def __init__(self, name, age): self.name = name self.age = age user2 = OptimizedUser("Bob", 25) # user2.new_attr = "test" # 错误!不能动态添加属性 # 内存对比 import sys user1_size = sys.getsizeof(user1.__dict__) # 较大的开销 user2_size = sys.getsizeof(user2) # 小得多的开销 # __slots__ 的注意事项 # 1. 子类也会继承 __slots__ 的限制 # 2. 每个子类也需要定义自己的 __slots__ 才能继续优化 # 3. 不适合需要动态属性的场景 # 4. 在创建大量实例时(如数百万个),内存节省非常显著 # 实际应用示例 class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y # 如果有数百万个点,使用 __slots__ 可以节省大量内存 points = [Point(i, i*2) for i in range(1000000)]
Python 3 中更强大的解包功能
# 在函数定义中使用 *args 和 **kwargs def func(*args, **kwargs): print(f"args: {args}") print(f"kwargs: {kwargs}") func(1, 2, 3, name="Alice", age=30) # args: (1, 2, 3) # kwargs: {'name': 'Alice', 'age': 30} # 在函数调用中解包 def add(a, b, c): return a + b + c args = [1, 2, 3] print(add(*args)) # 解包列表 kwargs = {"a": 1, "b": 2, "c": 3} print(add(**kwargs)) # 解包字典 # 在赋值中解包 a, *middle, b = [1, 2, 3, 4, 5] # a = 1, middle = [2, 3, 4], b = 5 first, *rest = [1, 2, 3, 4, 5] # first = 1, rest = [2, 3, 4, 5] *beginning, last = [1, 2, 3, 4, 5] # beginning = [1, 2, 3, 4], last = 5