一、什么是“字典传参”?

“字典传参”指的是:使用字典作为函数的参数进行传递或解包

有两种主要方式:

  1. 把字典整体作为一个参数传入函数
  2. \**字典 解包,把字典的键值对变成关键字参数传入函数

🧪 二、基础示例讲解

✅ 示例 1:把字典作为一个整体传进去

def greet(info):
    print(f"Hello, {info['name']} from {info['city']}!")

person = {'name': 'Alice', 'city': 'Shanghai'}
greet(person)  # 输出:Hello, Alice from Shanghai!

📌 解释
这个例子中,函数 greet() 接收一个参数 info,类型是字典。我们通过 info['name'] 来读取内容。


✅ 示例 2:使用 ** 解包字典传参

def greet(name, city):
    print(f"Hello, {name} from {city}!")

person = {'name': 'Alice', 'city': 'Shanghai'}
greet(**person)  # 解包成 greet(name='Alice', city='Shanghai')

📌 解释
这里的 **person 表示:把字典 person 的键值对解包成关键字参数传入函数。
等价于写 greet(name='Alice', city='Shanghai')


🧩 三、深层逻辑:*args vs **kwargs

  • *args 表示位置参数组成的元组
  • **kwargs 表示关键字参数组成的字典

我们可以定义函数同时接收两种形式:

def example(*args, **kwargs):
    print("位置参数:", args)
    print("关键字参数:", kwargs)

example(1, 2, a=3, b=4)
# 输出:
# 位置参数: (1, 2)
# 关键字参数: {'a': 3, 'b': 4}

🧵 四、函数定义时 vs 函数调用时的 **dict

✅ 定义函数时使用 **kwargs

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key} = {value}")

print_info(name='Tom', age=18)

✅ 调用函数时使用 **dict 传入多个参数

params = {'name': 'Tom', 'age': 18}
print_info(**params)

📌 总结

场景 用法
定义函数时 def f(**kwargs): 表示函数可以接受任意关键字参数
调用函数时 f(**字典) 解包字典作为关键字参数传入

🎯 五、字典传参的常见应用场景

1. 动态参数组合

def connect(host, port, user):
    print(f"Connecting to {host}:{port} as {user}")

config = {'host': 'localhost', 'port': 3306, 'user': 'root'}
connect(**config)

适用于配置项不固定或来自外部数据源的情况。


2. 传递参数给其他函数(中转)

def func_a(**kwargs):
    func_b(**kwargs)

def func_b(x, y):
    print(x + y)

func_a(x=1, y=2)

适合封装框架、装饰器等传递多层参数。


3. 结合默认参数使用

def download(url, method='GET', headers=None):
    print(f"{method} {url}")

params = {'url': 'http://example.com'}
download(**params)  # 使用默认 method

🧯 六、注意事项与坑

⚠️ 1. 字典必须和参数名完全匹配

def say(name, age):
    print(name, age)

d = {'name': 'Tom', 'gender': 'Male'}
say(**d)  # 报错:TypeError: got an unexpected keyword argument 'gender'

🧩 解决方案:过滤或提前判断字典的 key 是否匹配。


⚠️ 2. 字典是可变对象,修改会影响原字典

def change(d):
    d['x'] = 100

data = {'x': 1}
change(data)
print(data)  # {'x': 100}

🧩 如果你不想改动原字典,可以在函数内部复制一份:d = d.copy()


🪄 七、类比记忆:像“拆快递”

  • 直接传字典就像“送来一个完整的快递盒子”
  • ** 解包就像“把快递里的东西一件一件摊开递给你”

✅ 总结:一图胜千言

                函数定义            函数调用
-----------------------------------------------
位置参数:     def f(a, b)         f(1, 2)
关键字参数:   def f(a, b)         f(a=1, b=2)
可变参数:     def f(*args)        f(1, 2, 3)
关键字可变参数:def f(**kwargs)    f(**{'a':1, 'b':2})