函数基础
学会定义函数、参数传递、返回值和文档字符串
函数基础
函数是把一段代码打包起来、可以反复调用的工具。它是编程中最核心的抽象手段。
学完本章你将掌握: 定义函数、参数类型、返回值、作用域、以及 Python 特有的参数技巧。
一、为什么需要函数
没有函数时,代码重复、难维护:
python
# 不用函数:同样的逻辑写三遍
print("===== 小明 =====")
print("开始处理...")
print("处理完成!")
print("===== 小红 =====")
print("开始处理...")
print("处理完成!")
print("===== 小刚 =====")
print("开始处理...")
print("处理完成!")
用函数后,简洁且易修改:
python
def process_user(name):
print(f"===== {name} =====")
print("开始处理...")
print("处理完成!")
process_user("小明")
process_user("小红")
process_user("小刚")
二、定义和调用函数
python
# def 关键字定义
def greet():
print("你好!")
# 调用函数
greet()
带参数的函数:
python
def greet_user(name):
print(f"你好,{name}!")
greet_user("小明")
greet_user("小红")
💡 参数 vs 实参:定义时的
name叫形参,调用时传的"小明"叫实参。
三、返回值
python
def add(a, b):
return a + b
result = add(3, 5)
print(result) # 8
# 返回多个值(实际是返回元组)
def get_user_info():
return "小明", 20, "北京"
name, age, city = get_user_info() # 拆包接收
print(name, age, city)
# 提前返回(常用模式)
def check_age(age):
if age < 0:
return "无效年龄"
if age < 18:
return "未成年人"
return "成年人"
print(check_age(25)) # 成年人
💡 函数没有 return 时,默认返回 None。 这就是为什么
print(print("hello"))会输出None。
四、参数类型
位置参数(最常用)
python
def describe(name, age, city):
print(f"{name},{age}岁,来自{city}")
describe("小明", 20, "北京")
默认参数
python
def greet(name, greeting="你好"):
print(f"{greeting},{name}!")
greet("小明") # 你好,小明!
greet("小明", greeting="早上好") # 早上好,小明!
⚠️ 默认参数陷阱:默认值不要用可变对象!
python
# ❌ 错误做法
def add_item(item, items=[]):
items.append(item)
return items
print(add_item("a")) # ['a']
print(add_item("b")) # ['a', 'b'] ← 累积了!不是预期的!
# ✅ 正确做法
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
关键字参数
python
def order(item, quantity=1, price=0):
return f"购买 {quantity} 个 {item},共 {quantity * price} 元"
# 按名称传参,顺序任意
print(order(quantity=3, price=10, item="苹果"))
仅限关键字参数(Python 3+)
python
def config(*, host, port, debug=False):
print(f"连接 {host}:{port},调试: {debug}")
config(host="localhost", port=8000)
# config("localhost", 8000) # 报错,必须使用关键字
五、*args 和 **kwargs
接收任意数量的参数:
python
# *args:接收任意数量的位置参数(打包为元组)
def sum_all(*args):
total = 0
for n in args:
total += n
return total
print(sum_all(1, 2, 3)) # 6
print(sum_all(1, 2, 3, 4, 5)) # 15
# **kwargs:接收任意数量的关键字参数(打包为字典)
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="小明", age=20, city="北京")
python
# 实际应用:通用的日志函数
def log(message, **metadata):
print(f"[日志] {message}")
for k, v in metadata.items():
print(f" {k}: {v}")
log("用户登录", user="小明", ip="192.168.1.1", status="成功")
六、函数注解(类型提示)
Python 3.5+ 支持类型提示(不影响运行,但提升代码可读性):
python
def greet(name: str, age: int) -> str:
return f"{name},{age}岁"
print(greet("小明", 20))
# 完整的类型提示
from typing import List, Dict, Optional
def process_scores(
students: List[str],
scores: Dict[str, float],
bonus: Optional[int] = None
) -> Dict[str, float]:
result = {}
for name in students:
score = scores.get(name, 0)
if bonus:
score += bonus
result[name] = score
return result
七、文档字符串 (docstring)
python
def calculate_bmi(weight: float, height: float) -> str:
"""
计算 BMI 指数并返回健康建议。
参数:
weight: 体重(kg)
height: 身高(m)
返回:
健康建议字符串
示例:
>>> calculate_bmi(70, 1.75)
'正常体重'
"""
bmi = weight / (height ** 2)
if bmi < 18.5:
return "偏瘦"
elif bmi < 24:
return "正常体重"
else:
return "偏胖"
# 查看文档
print(calculate_bmi.__doc__)
八、作用域
python
total = 100 # 全局变量
def calculate():
local = 50 # 局部变量
print(f"可以读全局变量: {total}")
print(f"局部变量: {local}")
calculate()
# print(local) # ❌ NameError:不能访问局部变量
# 函数内修改全局变量要用 global
counter = 0
def increment():
global counter
counter += 1
increment()
print(counter) # 1
小结
def定义函数,return返回结果- 参数类型:位置参数、默认参数、关键字参数、
*args、**kwargs - 类型提示 (
str,int) 提升可读性,不强制检查 - 默认参数不要用可变对象
- 函数内变量是局部的,要用全局变量时加
global
小练习
- 写一个函数
is_prime(n)判断一个数是否为质数 - 写一个函数
max_of_three(a, b, c)返回三个数中的最大值 - 写一个函数
count_words(text)统计一段文字中每个单词的出现次数(回顾字典!)
💬 下一章预告:学完函数基础,下一章学习异常处理——让程序优雅地应对错误而不崩溃。