在Python开发中,我们经常需要处理以下场景:
传统参数传递方式的局限性:
def add(a, b):
return a + b
nums = (3, 5)
add(nums[0], nums[1]) # 需要手动解包
def show_info(name, age, city):
print(f"{name} | {age}岁 | 来自{city}")
data = ['王伟', 25, '北京']
show_info(*data) # 等价于 show_info('王伟', 25, '北京')
# 输出:王伟 | 25岁 | 来自北京
def config_server(host, port, timeout=10):
print(f"服务器配置:{host}:{port}, 超时:{timeout}s")
settings = {'host': '127.0.0.1', 'port': 8080}
config_server(**settings) # 输出:服务器配置:127.0.0.1:8080, 超时:10s
def create_order(product, price, *, customer, address):
print(f"{customer}订购{product},价格{price},配送至{address}")
args = ['手机', 2999]
kwargs = {'customer': '李女士', 'address': '上海浦东'}
create_order(*args, **kwargs)
# 输出:李女士订购手机,价格2999,配送至上海浦东
def process_data(name, (x, y), options):
print(f"{name}的坐标:({x}, {y})")
print("选项设置:", options)
data = ['雷达站', (34.5, 118.2), {'visible': True}]
process_data(*data)
# 输出:
# 雷达站的坐标:(34.5, 118.2)
# 选项设置: {'visible': True}
def dynamic_args(*args, **kwargs):
print("位置参数:", args)
print("关键字参数:", kwargs)
dynamic_args(*range(3), **{'a':1, 'b':2})
# 输出:
# 位置参数: (0, 1, 2)
# 关键字参数: {'a': 1, 'b': 2}
def sum_powers(n, *numbers):
return sum(num**n for num in numbers)
values = (2, 3, 4)
print(sum_powers(3, *values)) # 2³ + 3³ + 4³ = 8 + 27 + 64 = 99
def csv_to_json(*row_data, headers):
return {header: value for header, value in zip(headers, row_data)}
headers = ['name', 'email', 'phone']
data_row = ['张三', '[email protected]', '13800138000']
print(csv_to_json(*data_row, headers=headers))
# 输出:{'name': '张三', 'email': '[email protected]', 'phone': '13800138000'}
def validate_params(func):
def wrapper(*args, **kwargs):
print("验证参数:")
print("位置参数:", args)
print("关键字参数:", kwargs)
return func(*args, **kwargs)
return wrapper
@validate_params
def calculate(x, y):
return x * y
calculate(3, y=4)
# 输出:
# 验证参数:
# 位置参数: (3,)
# 关键字参数: {'y': 4}
# 返回:12
class APIHandler:
def __init__(self):
self.endpoints = {
'user': self.get_user,
'product': self.get_product
}
def call_endpoint(self, endpoint, *args, **kwargs):
return self.endpoints[endpoint](*args, **kwargs)
def get_user(self, user_id):
return f"用户信息:ID{user_id}"
def get_product(self, product_id):
return f"商品详情:ID{product_id}"
handler = APIHandler()
print(handler.call_endpoint('user', 123)) # 用户信息:ID123
print(handler.call_endpoint('product', 456)) # 商品详情:ID456
def example(a, b, c=0):
pass
# 正确用法
example(*[1, 2], **{'c': 3})
# 错误示例
try:
example(*[1, 2, 3, 4]) # 参数过多
except TypeError as e:
print(f"错误:{e}") # example() takes 2 positional arguments but 4 were given
def set_config(host, port):
print(f"配置:{host}:{port}")
try:
set_config(**{'hostname': 'localhost', 'port': 80}) # 键名不匹配
except TypeError as e:
print(f"错误:{e}") # got an unexpected keyword argument 'hostname'
from typing import Iterable
def safe_unpack(values: Iterable, default=None):
"""安全拆包工具函数"""
try:
a, b, *rest = values
return a, b, rest
except ValueError:
return default
print(safe_unpack([1, 2, 3, 4])) # (1, 2, [3, 4])
print(safe_unpack([1])) # None
# 不推荐
def sum_values(*args):
return sum(args)
values = [1, 2, 3, 4]
sum_values(*values) # 多一次拆包操作
# 推荐直接传递可迭代对象
def sum_values(values):
return sum(values)
def process_large_data(*data_stream):
count = 0
total = 0
for num in data_stream:
count += 1
total += num
return total / count
# 使用生成器表达式避免内存爆炸
big_data = (x for x in range(1000000))
print(process_large_data(*big_data))
函数拆包的三大核心价值:
通过掌握函数拆包技术,您将能够编写出更加灵活、健壮的Python代码,在数据处理、API设计等领域大显身手!