解包运算符 (Unpacking Operators)

* 解包运算符

用于解包可迭代对象(列表、元组、字符串等)

# 列表解包
numbers = [1, 2, 3]
print(*numbers)  # 输出: 1 2 3

# 函数参数解包
def add(a, b, c):
    return a + b + c

result = add(*numbers)  # 等价于 add(1, 2, 3)
print(result)  # 输出: 6

# 合并列表
list1 = [1, 2]
list2 = [3, 4]
combined = [*list1, *list2]  # [1, 2, 3, 4]

# 字符串解包
word = "hello"
print(*word)  # 输出: h e l l o

** 字典解包运算符

** 是 Python 的字典解包操作符,它会把字典中的键值对作为关键字参数传递给函数

   llm_params = {
       "model": model_name,
       "temperature": 0.1,
       "streaming": True,
       "openai_api_key": api_key,
       "openai_api_base": base_url,
   }
   llm_params.update(kwargs)  # 添加额外的参数
   
   # 这两行代码是等价的:
   instance = ChatOpenAI(**llm_params)
   instance = ChatOpenAI(
       model=model_name,
       temperature=0.1,
       streaming=True,
       openai_api_key=api_key,
       openai_api_base=base_url,
       # ... 其他来自 kwargs 的参数
   )
  • 灵活性:可以动态添加或修改参数
  • 代码简洁:避免手动列出所有参数
  • 可扩展性:通过 kwargs 可以传入额外的参数而不需要修改核心代码

打包运算符 (Packing Operators)

* 打包运算符

用于收集位置参数

# 收集所有位置参数
def sum_all(*args):
    return sum(args)

print(sum_all(1, 2, 3, 4))  # 输出: 10
print(sum_all(1, 2))        # 输出: 3

# 混合使用
def process_data(name, *numbers):
    print(f"姓名: {name}")
    print(f"数字: {numbers}")

process_data("李四", 1, 2, 3, 4)
# 输出:
# 姓名: 李四
# 数字: (1, 2, 3, 4)

** 打包运算符

用于收集关键字参数

# 收集所有关键字参数
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="王五", age=30, city="北京")
# 输出:
# name: 王五
# age: 30
# city: 北京

# 混合使用
def create_user(name, age, **extra_info):
    user = {"name": name, "age": age}
    user.update(extra_info)
    return user

user = create_user("赵六", 28, city="上海", job="工程师")
print(user)  # {'name': '赵六', 'age': 28, 'city': '上海', 'job': '工程师'}

实际应用场景

函数装饰器

def log_function(func):
    def wrapper(*args, **kwargs):
        print(f"调用函数: {func.__name__}")
        result = func(*args, **kwargs)
        print(f"函数返回: {result}")
        return result
    return wrapper

@log_function
def add(a, b):
    return a + b

add(3, 5)  # 输出调用和返回信息

类继承

class BaseConfig:
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

class DatabaseConfig(BaseConfig):
    def __init__(self, host="localhost", port=5432, **kwargs):
        super().__init__(host=host, port=port, **kwargs)

db_config = DatabaseConfig(host="192.168.1.100", password="secret")
print(db_config.host)      # 192.168.1.100
print(db_config.port)      # 5432
print(db_config.password)  # secret

数据转换

# 列表转元组
numbers = [1, 2, 3]
tuple_numbers = (*numbers,)  # (1, 2, 3)

# 字典合并
default_settings = {"theme": "dark", "language": "zh"}
user_settings = {"theme": "light"}
final_settings = {**default_settings, **user_settings}
# {'theme': 'light', 'language': 'zh'}

注意事项

解包顺序:后面的会覆盖前面的

dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
result = {**dict1, **dict2}  # {'a': 1, 'b': 3, 'c': 4}

性能考虑:解包操作会创建新的对象

# 对于大列表,解包可能影响性能
large_list = list(range(10000))
# 使用解包会创建新的列表

Python 版本:* 和 ** 在 Python 3.5+ 中支持更多用法

# Python 3.5+ 支持
matrix = [[1, 2], [3, 4]]
flattened = [*matrix[0], *matrix[1]]  # [1, 2, 3, 4]

这些运算符让 Python 代码更加灵活和简洁,是函数式编程和动态参数处理的重要工具。