目标读者:编程新手 | 转行者 | 需系统掌握函数用法的开发者
目录
一、函数是什么?为什么需要函数?
二、函数基础语法详解
1. 定义与调用
2. 返回值:函数的输出结果
3. 参数传递机制
4. 案例:计算BMI指数
三、变量作用域:理解局部与全局
1. 局部变量
2. 全局变量
四、函数进阶:lambda与高阶函数
1. lambda匿名函数
2. 高阶函数
五、函数高级特性
1. 装饰器:增强函数功能
2. 递归函数
六、实战案例:文件处理工具
函数定义:函数是一段可重复调用的代码块,用于封装特定功能。
核心价值(需要函数的原因):
避免重复代码:相同逻辑只需编写一次
提升可读性:通过命名明确功能意图
便于维护:修改时只需调整函数内部
可以类比为厨房的微波炉,微波炉(函数)的功能是加热食物,要想正确启动微波炉(函数)就需要打开微波炉并放入食物(输入),经过加热之后,就可以将热的食物(结果)拿出来了。
故而微波炉的工作过程——
输入:放入食物(参数)
处理:设定加热程序(函数体)
输出:得到加热后的食物(返回值)
# 定义函数
def greet(name):
"""向指定用户打招呼""" # 文档字符串(说明函数功能)
print(f"Hello, {name}!")
# 调用函数
greet("CSDN读者") # 输出:Hello, CSDN读者!
✅ 关键点:
def
为定义函数的关键字
函数名遵循变量命名规则(建议动词开头,如get_data
)
使用 return
返回数据(可返回任意类型)
无 return
语句时默认返回 None
参数类型 | 说明 | 示例 |
---|---|---|
位置参数 | 按定义顺序传递 | func(a, b) → func(1,2) |
关键字参数 | 指定参数名传递 | func(b=2, a=1) |
默认参数 | 定义时赋值,调用可省略 | def func(a=0) |
可变参数 | 接收任意数量参数(*args ) |
def func(*numbers) |
# 按位置传递参数
def func(a, b):
return a+b
func(1,2) # 此时传入1给a,2给b。
# 按关键字传递参数
def func(a, b):
return a+b
func(b=2, a=1) # 此时声明了2传给b,1传给a。
# 默认参数
def func(a=0) # 定义时赋值,调用可省略
return a+5
b = func() # 此时a默认传入0,故返回0+5=5。
# 可变参数
def func(*numbers): # 传入的参数会被打包成一个元组trule
if not numbers: # 防止空参数
return 0
return numbers[0] * 2
c1 = func(2) # 输出:4; numbers此时为(2,)
c2 = func('a','b',2) # 输出:'aa'; numbers此时为('a','b',2)
print(c1) # 4
print(c2) # 'aa'
def calculate_bmi(height, weight):
"""
计算BMI指数
:param height: 身高(米)
:param weight: 体重(千克)
:return: BMI值(保留两位小数)
"""
bmi = weight / (height ** 2)
return round(bmi, 2)
result = calculate_bmi(1.75, 70)
print(f"您的BMI指数:{result}") # 输出:22.86
在函数内部定义,仅函数内可用
def test():
local_var = 10
print(local_var) # 正常输出
test()
print(local_var) # 报错:NameError
在函数外定义,全程序可用
函数内修改需用 global
声明
count = 0
def increment():
global count
count += 1
increment()
print(count) # 输出:1
最佳实践:
避免滥用全局变量(易引发意外修改)
优先使用参数和返回值传递数据
单行简单函数,无需定义名称
# 传统函数定义
def add(a, b):
return a + b
# lambda等效写法
add_lambda = lambda a, b: a + b
print(add(2,3)) # 5
print(add_lambda(2,3)) # 5
适用场景:
临时简单操作(如排序key
参数)
students = [{"name": "Alice", "age": 20}, {"name": "Bob", "age": 18}]
students.sort(key=lambda x: x["age"]) # 按年龄排序
# 相当与 students.sort(key="age")
# sort是排序函数,可以理解为本地写好了的函数,可以直接使用
定义:接收函数作为参数或返回函数的函数
典型应用:
1. map():对集合元素批量处理
"""
map()函数作用:
对可迭代对象(如列表、元组)的每个元素应用一个函数,
并返回一个迭代器(需要转换为列表才能直接查看结果)。
"""
# -----------------------实例1-----------------------------------
nums = [1, 2, 3]
squared = list(map(lambda x: x**2, nums))
# lambda x: x**2 -> 匿名函数,接收一个参数 x,返回其平方。
# map(lambda x: x**2, nums) -> 将这个函数依次作用于 nums 的每个元素
# list(……) -> 结果转变为list
print(squared) # [1, 4, 9]
# -----------------------实例2-----------------------------------
a = [1, 2, 3]
b = [4, 5, 6]
summed = list(map(lambda x, y: x + y, a, b))
print(summed) # 输出:[5, 7, 9]
2. filter():过滤符合条件的元素
"""
filter()作用:过滤可迭代对象中的元素,保留满足条件的元素。
- 函数必须返回一个布尔值(True 或 False)。
- 只保留函数返回 True 的元素。
"""
# --------------------过滤偶数-----------------------
numbers = [10, 3, 7, 15, 6]
even_nums = list(filter(lambda x: x%2 ==0, numbers))
print(even_nums) # [10, 6]
# -------------------过滤字符串长度-------------------
words = ["apple", "bat", "cat", "dog", "elephant"]
long_words = list(filter(lambda s: len(s) > 3, words))
print(long_words) # 输出:['apple', 'elephant']
3. reduce():累积计算(需导入functools
)
"""
reduce()作用:对可迭代对象的元素进行累积计算,最终返回一个结果。
"""
from functools import reduce
product = reduce(lambda x,y: x*y, [1,2,3,4])
# 1*2=2 --> 2*3=6 --> 6*4=24
print(product) # 24
功能:在不修改原函数代码的前提下添加新功能
案例:记录函数执行时间
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 执行耗时:{end - start:.2f}秒")
return result
return wrapper
@timer
def long_task():
time.sleep(2)
long_task() # 输出:long_task 执行耗时:2.00秒
定义:函数内部调用自身
案例:计算阶乘
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n-1)
print(factorial(5)) # 120
注意事项:
必须设置终止条件
递归层数过多会导致栈溢出(Python默认深度约1000层)
需求:开发函数集实现以下功能:
统计文本文件词频
批量重命名目录下文件
实现代码:
import os
# 功能1:统计词频
def count_words(file_path):
word_count = {}
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
words = line.strip().split()
for word in words:
word_count[word] = word_count.get(word, 0) + 1
return word_count
# 功能2:批量重命名
def batch_rename(dir_path, prefix):
for idx, filename in enumerate(os.listdir(dir_path)):
src = os.path.join(dir_path, filename)
dst = os.path.join(dir_path, f"{prefix}_{idx+1}{os.path.splitext(filename)[1]}")
os.rename(src, dst)
# 使用示例
print(count_words("demo.txt"))
batch_rename("./docs", "report")