函数的定义与调用
最基本的函数结构如下:
python
def greet(name):
return f"Hello, {name}!"
print(greet("Alice"))
def定义函数- 调用时传入对应参数
如果参数数量或顺序不匹配,就会报错,这是最常见的问题之一。
默认参数
默认参数的作用是让函数调用更灵活,同时减少重复传参。
python
def greet(name, prefix="Hello"):
return f"{prefix}, {name}!"
print(greet("Alice")) # Hello, Alice!
print(greet("Alice", "Hi")) # Hi, Alice!
默认参数的规则是:
- 必须放在普通参数后面
- 调用时可以选择是否覆盖
默认参数的"坑"
直接看例子:
python
def append_item(item, lst=[]):
lst.append(item)
return lst
print(append_item(1)) # [1]
print(append_item(2)) # [1, 2]
很多人以为第二次会返回 [2],但结果是 [1, 2]。原因是,默认参数只在函数定义时创建一次。
正确写法是:
python
def append_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
可变参数 *args、**kwargs
当参数数量不固定时,就需要用到可变参数。
*args(接收位置参数)
先看一个例子:
go
def func(*args):
print(args)
print(type(args))
func(1, 2, 3)
# (1, 2, 3)
# <class 'tuple'>
args 本质是一个元组,即Python会把所有位置参数收集起来,按顺序 打包成一个元组,相当于在函数内部,args = (1, 2, 3)。
css
def add(a, b, c):
return a + b + c
nums = (1, 2, 3)
print(add(*nums)) # 等价于 add(1, 2, 3)
在函数调用时,* 的作用是:把一个可迭代对象拆成多个位置参数。 * 解包不仅限于元组,只要是可迭代对象(list、tuple、甚至字符串)都可以。
python
num = (1,2,3,4,5)
print(*num) # 1 2 3 4 5
# ----
def show(a, b, c):
print(a, b, c)
show(*"abc") # a b c
**kwargs(接收关键字参数)
同样,我们先来看一个例子:
css
def show_info(**kwargs):
print(kwargs)
print(type(kwargs))
show_info(name="Alice", age=20)
# {'name': 'Alice', 'age': 20}
# <class 'dict'>
**kwargs 在函数内部其实就是一个字典(dict) 。调用时传入的所有关键字参数,都会被收集到这个字典里。
在函数调用时,** 的作用是把一个字典拆开,变成多个关键字参数传给函数。
例如:
scss
def connect(host, port):
print(host, port)
config = {
"host": "localhost",
"port": 3306
}
connect(**config) # localhost 3306,相当于执行了 connect(host="localhost", port=3306)
注意:字典的 key 必须和函数参数名一致,否则会报错。
回调函数
函数在 Python可以作为参数传递,称为回调函数。回调函数本身不复杂,但是有一些细节需要注意。
- 回调要传函数,不要加括号
直接来看一个例子:
scss
def apply(func):
return func()
def say_hi():
print("hi")
apply(say_hi()) # ❌ 错误写法
这段代码的问题在于,say_hi()在传参之前就已经执行了,传进去的是返回值(这里是 None)。正确写法应该是直接传函数本身,不要加括号。正确写法是:apply(say_hi)。
- 回调函数的参数要匹配
python
def add(a, b):
return a + b
def apply(func):
return func(10)
apply(add) # ❌ 报错
apply 只传了一个参数,但 add 需要两个。要么修改add为只有一个参数的函数,要么lambda来适配参数,即apply(lambda x: add(x, 5))。
lambda是一个轻量级的匿名函数写法 ,适合在需要函数的地方,快速写一个"一次性的小逻辑"。lambda的结构为:lambda 参数: 返回值。例如:
pythondef add(x, y): return x + y # 用 lambda 写: add = lambda x, y: x + y
lambda常用于回调函数,可以作为传入函数的参数。但lambda并不是def的完全替代,它有明显限制:1)只能写一行表达式
2)不能写复杂的逻辑,例如多行代码、循环、复杂判断
- 回调参数的应用场景:
1)排序(最常见)
ini
data = ["apple", "banana", "cherry"]
print(sorted(data, key=len))
这里 key=len 就是回调函数,意思是按照字符串长度排序。
2)简单策略切换
python
def process(x, func):
return func(x)
print(process(10, lambda x: x * 2))
print(process(10, lambda x: x + 5))
不同逻辑,通过不同回调实现。
3) 事件 / 异步
在一些框架中(如 GUI、网络请求),回调用于"某个事件发生后执行"。例如伪代码:
css
button.on_click(handle_click)
点击按钮时,才执行 handle_click
总结
这篇文章系统讲解了Python函数参数机制,涵盖基础定义、默认参数、可变参数*args和**kwargs的使用与解包技巧,以及回调函数的正确传参方式和应用场景。