6.1 函数定义与调用语法
在Python中,函数就像一个魔法盒子,你把东西放进去(输入参数),它就会按照设定好的规则处理,然后给你返回结果。函数的定义使用def关键字,后面跟着函数名和括号,括号里可以有参数,最后以冒号结束。函数体需要缩进,通常会包含一些处理逻辑,最后可能用return语句返回结果。
python
# 定义一个简单的打招呼函数
def greet(name):
# name是参数,函数内部可以使用
message = f"你好, {name}!" # 创建问候消息
return message # 返回消息
# 调用函数
result = greet("小明") # 传入参数"小明"
print(result) # 输出: 你好, 小明!这里的关键点是:定义函数时用def,调用时直接写函数名加括号和参数。函数可以让代码复用,避免重复写相同的逻辑,简直是程序员的得力助手!
6.2 函数参数传递方式
Python中的参数传递有点像快递包裹,你寄出去的东西(实参)会被送到函数那里(形参)。主要有两种方式:位置参数和关键字参数。位置参数按顺序对应,关键字参数则通过参数名指定,更清晰但要注意顺序。
| 功能名称 | 实例调用方法 | 具体功能、注意事项、必需参数/可选参数 |
|---|---|---|
| 位置参数传递 | func(a, b) | 按参数定义顺序传递,必需参数必须提供 |
| 关键字参数传递 | func(param1=a, param2=b) | 通过参数名指定值,可读性高,顺序可变 |
python
# 定义一个计算矩形面积的函数
def calculate_area(length, width):
# length和width是位置参数
if length <= 0 or width <= 0:
raise ValueError("长度和宽度必须为正数") # 错误捕获
return length * width
# 使用位置参数调用
area1 = calculate_area(5, 3) # length=5, width=3
print(f"面积1: {area1}") # 输出: 面积1: 15
# 使用关键字参数调用
area2 = calculate_area(width=4, length=6) # 顺序可变
print(f"面积2: {area2}") # 输出: 面积2: 24
# 混合使用(位置参数在前,关键字参数在后)
try:
area3 = calculate_area(7, width=2) # 合法
print(f"面积3: {area3}") # 输出: 面积3: 14
except ValueError as e:
print(f"错误: {e}")注意:位置参数必须放在关键字参数前面,否则会报错。而且所有必需参数都必须被赋值,不然函数会抱怨!
6.3 返回值与无返回值函数
函数的返回值就像任务完成后的成果报告。如果函数有return语句,它会把结果带回来;如果没有return或者return后面没东西,函数就默认返回None,表示“没啥好说的”。
| 功能名称 | 实例调用方法 | 具体功能、注意事项、必需参数/可选参数 |
|---|---|---|
| 有返回值函数 | result = func() | 返回指定值,可用于后续计算 |
| 无返回值函数 | func() | 返回None,通常用于执行操作而非计算 |
python
# 有返回值的函数:计算平方
def square(x):
return x * x # 返回计算结果
# 无返回值的函数:打印日志
def log_message(message):
print(f"[日志] {message}") # 执行操作,无return
# 调用有返回值函数
num = 4
squared = square(num) # 获取返回值
print(f"{num}的平方是{squared}") # 输出: 4的平方是16
# 调用无返回值函数
log_result = log_message("程序启动") # 执行打印
print(f"log_message的返回值: {log_result}") # 输出: log_message的返回值: None
# 注意:即使不捕获返回值,函数也会执行
square(5) # 计算但不保存结果,浪费了!这里的小窍门是:如果你需要函数的结果,一定要用变量接收返回值;如果只是执行某个动作(比如打印或写文件),那就不需要关心返回值。
6.4 默认参数与关键字参数
默认参数就像是函数的“备胎”,当你不提供某个参数时,它就自动顶上。关键字参数则让你在调用时明确指定参数名,代码更易读。两者结合使用,能让函数更灵活,调用更方便。
| 功能名称 | 实例调用方法 | 具体功能、注意事项、必需参数/可选参数 |
|---|---|---|
| 默认参数设置 | def func(a, b=10) | b有默认值10,调用时可省略 |
| 关键字参数调用 | func(a=5, b=20) | 明确指定参数名,顺序无关 |
python
# 定义一个发送邮件的函数,带默认参数
def send_email(to, subject="无主题", body=""):
# to是必需参数,subject和body有默认值
if not to:
raise ValueError("收件人地址不能为空") # 错误捕获
email_content = f"收件人: {to}\n主题: {subject}\n内容: {body}"
return email_content # 返回邮件内容
# 只提供必需参数,使用默认值
email1 = send_email("user@example.com")
print(email1)
# 输出:
# 收件人: user@example.com
# 主题: 无主题
# 内容:
# 提供部分参数,覆盖默认值
email2 = send_email("boss@example.com", subject="项目更新")
print(email2)
# 输出:
# 收件人: boss@example.com
# 主题: 项目更新
# 内容:
# 使用关键字参数,顺序自由
try:
email3 = send_email(body="详情见附件", to="client@example.com", subject="报价单")
print(email3)
# 输出:
# 收件人: client@example.com
# 主题: 报价单
# 内容: 详情见附件
except ValueError as e:
print(f"错误: {e}")
# 注意:默认参数如果是可变对象(如列表),要小心!
def add_item(item, target_list=[]): # 危险!默认列表是共享的
target_list.append(item)
return target_list
# 测试可变默认参数的问题
list1 = add_item("苹果")
list2 = add_item("香蕉")
print(f"list1: {list1}, list2: {list2}") # 输出: list1: ['苹果', '香蕉'], list2: ['苹果', '香蕉']
# 哦不!两个列表竟然共享了同一个默认列表,这可不是我们想要的。重要提醒:默认参数如果是可变对象(比如列表、字典),会在多次调用间共享状态,容易出bug。安全做法是用None作为默认值,然后在函数内部初始化。例如:
python
# 安全的可变默认参数处理
def safe_add_item(item, target_list=None):
if target_list is None:
target_list = [] # 每次调用都创建新列表
target_list.append(item)
return target_list
# 测试安全版本
safe_list1 = safe_add_item("橙子")
safe_list2 = safe_add_item("葡萄")
print(f"safe_list1: {safe_list1}, safe_list2: {safe_list2}") # 输出: safe_list1: ['橙子'], safe_list2: ['葡萄']
# 这样就各自独立了,完美!