5.2 函数参数
上一节的参数是最基本的形式,这一节学几种更灵活的用法。
位置参数:按顺序对号入座
def introduce(name, age):
print(f"我叫{name},今年{age}岁")
introduce("小明", 18) # name="小明", age=18,按位置匹配
introduce(18, "小明") # ⚠️ 语法没错但逻辑错了:我叫18,今年小明岁
关键字参数:指名道姓地传
调用时写明参数名,顺序就无所谓了,可读性也更好:
introduce(age=18, name="小明") # 我叫小明,今年18岁
位置参数和关键字参数可以混用,但位置参数必须在前:
introduce("小明", age=18) # ✅
introduce(name="小明", 18) # ❌ SyntaxError
默认参数:可传可不传
定义时给参数一个默认值,调用时不传就用默认的:
def greet(name, greeting="你好"):
print(f"{greeting},{name}!")
greet("小明") # 你好,小明!(用默认值)
greet("小明", "早上好") # 早上好,小明!(覆盖默认值)
其实你已经见过:print("a", "b", sep="-") 里的 sep 就是默认参数(默认是空格)。
规则:默认参数必须放在没有默认值的参数后面。
def greet(greeting="你好", name): # ❌ SyntaxError
可变参数 *args:想传几个传几个
参数名前加 *,可以接收任意多个值,函数内部拿到的是一个元组:
def add_all(*nums):
print(nums) # 是个元组
total = 0
for n in nums:
total += n
return total
print(add_all(1, 2)) # 3
print(add_all(1, 2, 3, 4)) # 10
print() 能一次打印任意多个东西,就是用了这种机制。
💡 还有个
**kwargs接收任意多个关键字参数(得到字典),新手阶段见到认识即可,暂不深究。
新手大坑:默认参数不要用列表
def add_item(item, lst=[]): # ❌ 危险写法
lst.append(item)
return lst
print(add_item("a")) # ['a']
print(add_item("b")) # ['a', 'b'] ??怎么把上次的也带出来了
原因:默认值 [] 只在定义时创建一次,所有调用共享同一个列表。正确写法:
def add_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
现在记住结论就行:默认值只用数字、字符串、None 这类不可变的东西。
练习
- 写函数
power(base, n=2):计算 base 的 n 次方,n 默认为 2。验证power(3)是 9,power(2, 10)是 1024。 - 写函数
make_tea(tea, size="中杯", sugar="半糖"),打印一句"一杯{size}{sugar}的{tea}"。分别用纯位置参数、纯关键字参数各调用一次。 - 写函数
count_max(*nums),返回传入的所有数字中的最大值。
点击查看答案
# 1
def power(base, n=2):
return base ** n
print(power(3)) # 9
print(power(2, 10)) # 1024
# 2
def make_tea(tea, size="中杯", sugar="半糖"):
print(f"一杯{size}{sugar}的{tea}")
make_tea("乌龙茶", "大杯", "全糖")
make_tea(tea="乌龙茶", sugar="无糖")
# 3
def count_max(*nums):
biggest = nums[0]
for n in nums:
if n > biggest:
biggest = n
return biggest
print(count_max(3, 9, 2, 7)) # 9
本章小结
- 位置参数按顺序,关键字参数按名字
- 默认参数让调用更省事,但默认值别用列表/字典
*args接收任意个参数
下一节:5.3 变量作用域