Python函数的系统性教程,涵盖函数定义、参数规则、作用域和匿名函数四大核心模块,结合最新实践技巧与常见陷阱分析
一、函数定义与调用
1. 基本语法
使用def
关键字定义函数,包含函数名、参数列表和代码块:
# 语法结构
def 函数名称(参数1: int, 参数2: str , ......) -> str:代码块return f"Hello!"
# def: python 定义函数的关键字
# 函数名称: 命名规则参考下面介绍
# 参数: 调用函数时,需要出入的值
# :int: 表示传入参数的数据类型
# -> str: 表示该函数返回结果的数据类型
# return:通过此关键字返回给调用者处理完成的结果,可以不写则返回None;
# 如果需要返回多个值使用 , 隔开,返回的是一个元组# 调用函数
函数名称(值1, 值2, ......)# 无参数函数
def greet() -> str: # 类型提示增强可读性"""返回个性化问候语(Docstring说明)"""return f"Hello!"# 调用
result = geeet()
print(result) # 输出 Hello!# 有参数函数
def greet(name: str) -> str: # 类型提示增强可读性"""返回个性化问候语(Docstring说明)"""return f"Hello, {name}!"# 调用
result = greet('Yant')
print(result) ## 输出 Hello, Yant!
2. 函数的命名规则
- 使用
小写字母
和下划线
(snake_case),例如:calculate_sum。 - 函数名应使用
动词
或动词短语
,明确功能,例如:get_user_data。 - 避免模糊命名,使用具体、描述性的名称,例如避免使用process,而是用clean_data。
- 避免使用保留字和单字母名称,除非在特定上下文如循环中。
- 文档字符串(Docstring)的使用,虽然不是命名规则,但能提高可读性,可能作为补充。
3. 参数传递机制
值传递 vs 引用传递:不可变对象(如字符串)传值,可变对象(如列表)传引用
# int 是不可变类型,大概的意思是 num 的值直接给了 n
def test(n):print(n + 1)
m = 1
test(m)# list是可变类型,大概的意思是 调用函数时 nums的内存地址 --> 赋值给lst
def modify(lst):lst.append(4) # 原列表被修改
nums = [1, 2, 3]
modify(nums) # nums变为[1,2,3,4]# 这里可能描述不太恰当,不过可以大概这么理解
二、参数类型与规则
1. 参数分类
类型 | 语法 | 特性说明 | 样例 |
---|---|---|---|
位置参数 | def func(a, b) | 按顺序传入 | func(1, 2) 此时a=1,b=2;func(2,1) 此时a=2,b=1 |
默认参数 | def func(a=5) | 默认值在定义时计算 | 调用时可以不传值,a=5;调用时传值 func(10) 此时 a=10 |
可变位置参数 | *args | func(*args) 接收元组,允许不定长参数 | func(1, 2, 3,…) 此时 args=(1, 2, 3,…) |
可变关键字参数 | **kwargs | func(**kwargs)接收字典,处理命名参数 | func(a=1, b=2, c=3,…) 此时 kwargs = {‘a’:1, ‘b’:2, ‘c’:3, …} |
2. 参数顺序原则
必须遵循顺序:必选参数 → 默认参数 → *args → 命名关键字参数 → **kwargs
❌ 错误示例:def func(a=1, b)
(默认参数不能在必选参数前)
3. 参数陷阱与规避
可变默认值问题:默认参数若为列表/字典,多次调用会共享同一对象
,这里可能会遇到坑才能理解
# 错误写法
def bug_func(data, lst=[]):lst.append(data)return lst# 正确:用None占位
def safe_func(data, lst=None):lst = [] if lst is None else lstlst.append(data)return lst
三、作用域与变量可见性
1. 作用域层级(LEGB规则)
- Local:函数内部变量
- Enclosing:闭包外层函数变量(关于闭包后面才讲,此处留个印象)
- Global:模块级全局变量
- Built-in:内置函数(如print)
# 这是一个py文件
global_val= 1 # 这是一个全局变量,这个py文件都可以引用
def location():local_val = 2 # 这个一个局部变量,只在函数内部可以引用print(global_val) # 输出 1
print(local_val) # 直接报错
2. 变量修改规则
- 全局变量:需用global声明修改
count = 10
def increment():global countcount += 1
四、匿名函数(Lambda)
1. 语法与特性
- 基础结构:lambda 参数: 表达式
square = lambda x: x ** 2 # 计算平方
- 适用场景:简单逻辑、高阶函数参数(如map/filter)
nums = [1, 2, 3]
squared = list(map(lambda x: x**2, nums)) # [1,4,9]
2. 使用建议
- 避免滥用:复杂逻辑用def定义,保持可读性
- 替代方案:列表推导式比map+lambda更简洁
# 推荐写法
squared = [x**2 for x in nums]
综合应用示例
def data_processor(data: list, *, prefix: str = "ID-", filter_func: callable) -> dict:"""处理数据并过滤(使用关键字参数与函数参数)"""processed = {f"{prefix}{i}": item for i, item in enumerate(data)}return {k: v for k, v in processed.items() if filter_func(v)}# 调用示例
result = data_processor([10, 2, 15], filter_func=lambda x: x > 5)
# 输出:{'ID-0': 10, 'ID-2': 15}
关于函数想了很久,没有想到太合适表达的方法,毕竟函数作为一个核心的知识点,里面后很多细节的地方,写的太细怕写得一塌糊涂,写得简单又怕知识点不全,希望通过这篇文章能给个位一个入门的认知,后续在使用的时候多多积累!!!