默认参数
调用时不传就用默认值:
def greet(name, greeting="你好"):
return f"{greeting}, {name}"
greet("WadeLy") # '你好, WadeLy'
greet("WadeLy", "嗨") # '嗨, WadeLy'
greet("WadeLy", greeting="嗨") # 关键字传参,更清晰
默认参数必须在普通参数后面:
def f(a=1, b): # SyntaxError
pass
关键字参数 vs 位置参数
def order(food, size, spicy):
return f"{size} {food} {'辣' if spicy else '不辣'}"
# 位置传参
order("拉面", "大", True)
# 关键字传参(顺序无所谓,可读性更好)
order(food="拉面", size="大", spicy=True)
order(spicy=True, food="拉面", size="大") # 也对
# 混用:位置在前,关键字在后
order("拉面", size="大", spicy=True)
*args:任意个位置参数
def total(*nums):
return sum(nums)
total(1, 2, 3) # 6
total(1, 2, 3, 4, 5) # 15
*nums 把所有位置参数收集成元组。
**kwargs:任意个关键字参数
def show(**info):
for k, v in info.items():
print(f"{k}: {v}")
show(name="WadeLy", age=30, city="深圳")
# name: WadeLy
# age: 30
# city: 深圳
**info 收集成字典。
全部组合(顺序固定)
def f(a, b, *args, c=10, **kwargs):
print(a, b, args, c, kwargs)
f(1, 2, 3, 4, c=20, x=100, y=200)
# 1 2 (3, 4) 20 {'x': 100, 'y': 200}
顺序:普通参数 → *args → 默认参数 → **kwargs。
拆包传参
nums = [1, 2, 3]
def add(a, b, c):
return a + b + c
add(*nums) # 等价 add(1, 2, 3) → 6
config = {"a": 1, "b": 2, "c": 3}
add(**config) # 等价 add(a=1, b=2, c=3) → 6
* 拆列表/元组,** 拆字典。
默认参数的坑
不要用可变对象做默认值:
def append_item(item, lst=[]): # 坑!
lst.append(item)
return lst
append_item(1) # [1]
append_item(2) # [1, 2]!? 默认值被共享了
# 正确写法
def append_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
下一篇讲作用域——变量从哪里来、能到哪里去。