一、函数的核心知识点
1.函数的参数
a.分类
b.参数类型的执行顺序
规则:位置(必选)参数→默认参数→*arg
→命名关键字参数→**kwargs
def func(a=1, b):
pass
def func(b, a=1):
pass
c.默认参数的陷阱:可变对象
默认参数的值在函数定义时就被计算并存储,如果默认值是可变对象(如列表、字典),多次调用时会共享同一对象
def func(a,lst=[]):
lst.append(a)
print(lst)
func(a)
func(b)
[1]
[1, 2]
假如你想默认参数是可变参数,又不想共享该对象,将target赋值为None。用 None
占位,并在函数内初始化:
def func(a, target=None):
if target is None:
lst = []
lst.append(a)
print(lst)
func(a)
func(b)
d.*args
和 **kwargs
的误用
- 定义函数时:
*args
收集多余的位置参数为元组,**kwargs
收集多余的关键字参数为字典。
- 调用函数时:
*
解包序列为位置参数,**
解包字典为关键字参数。
def func(a, b):
pass
args = (1, 2, 3)
func(*args)
def func(a, *args, b):
pass
func(1, 2, 3)
func(1, 2, b=3)
e.参数传递的混淆:位置vs关键字
def func(a,b):
pass
func(a=1, 2)
func(1, b=1)
f.【使用总结】
- 默认参数用不可变对象(如
None
、数字、字符串)。
- 严格遵循参数顺序:必选 → 默认 →
*args
→ 命名关键字 → **kwargs
。
- 明确参数类型:用命名关键字参数强制接口清晰性。
- 避免参数名与内置函数冲突。
- 理解可变/不可变参数的传递机制。
2.函数的作用域
- 全局变量:
global
- 局部变量
nonlocal
关键字
a.全局变量
x = 10
def func():
print(x)
func()
def func2():
x = 20
print(x)
func2()
print(x)
def func1():
global x
x = 20
print(x)
func1()
print(x)
b.局部变量
- 定义: 在函数内部定义的变量,只在函数内部有效
- 作用域: 函数内部
- 特点:
- 函数执行结束后,局部变量会被销毁
- 不同函数中的同名局部变量互不影响
# 案例
def func():
y = 5 # 局部变量,只在func内部有效
print(y)
y = 10 # 全局变量
print(y)
func()
c.nonlocal关键字
- 作用:在嵌套函数中,声明变量属于外层函数的作用域,并允许修改它
- 使用场景:闭包、多层嵌套函数中共享状态
- 限制:
- 外层函数必须定义该变量
- 只能用于嵌套函数中(python3)
def outer()
z = 10
print(z)
def inner():
nonlocal z
z = 20
inner()
print(z)
outer()
d.【核心原则】:
尽量使用局部变量,避免全局变量;需要共享状态时,优先用 nonlocal
或类(Class)替代全局变量。
3.闭包与装饰器
a.闭包
b.装饰器
-
定义:是一个接收函数作为参数,返回新函数的高阶函数。用于在不修改原函数代码的前提下增强其功能。装饰器本质上是闭包的一种应用。其中@simple_decorator
相当于my_func = simple_decorator(my_func)
def simple_decorator(func):
def wrapper():
print('函数回调之前')
func()
print('函数回调之后')
return wrapper
@simple_decorator
def my_func():
print('函数执行.....')
-
处理参数和返回值
def universal_decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result
return wrapper
-
带参数的装饰器:需要三层嵌套
def repeat(n_times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n_times):
func(*args, **kwargs)
return wrapper
return decorator
-
使用场景
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(f'调用函数:{func.__name__},参数:{args}, {kwargs}')
result = func(*args, **kwargs)
print(f"函数 {func.__name__} 执行完毕")
return result
return wrapper
@log
def add(a,b):
return a+b
print(add)
"""
实现:函数运行的时间的记录
"""
import time
import functools
def log_execution_time(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
func(*args, **kwargs)
end_time = time.perf_counter()
print('{} took:{}ms'.format(func.__name__, (end_time-start_time)*1000))
return wrapper
@log_execution_time
def my_func():
print('hello!')
my_func()
def check_admin(user_type):
def decorator(func):
def wrapper(*args, **kwargs):
if user_type != "admin":
raise PermissionError("无权限操作!")
return func(*args, **kwargs)
return wrapper
return decorator
@check_admin(user_type="admin")
def delete_file(filename):
print(f"删除文件: {filename}")
delete_file("test.txt")
@check_admin(user_type="user")
def read_file(filename):
print(f"读取文件: {filename}")
read_file("data.txt")
import functools
"""保存结果"""
def cache_results(func):
cache = {}
@functools.wraps(func)
def wrapper(n):
cache[n] = my_func(n)
return cache
return wrapper
def my_func(n):
if 2 > n >= 0:
return n
return my_func(n - 1) + my_func(n - 2)
4.lambda匿名函数
a.基本语法
lambda arguments:expression
注意:闭包中的延迟绑定问题,例如在循环中创建 lambda
时,变量可能最终共享同一个值
b.使用场景
-
高阶函数的参数
-
快熟定义简单的函数
squares = list[map(lambda x:x**2,[1,2,3])]
-
动态参数绑定
button.bind("<Button-1>", lambda event: callback(param1, param2))
-
字典排序或操作
d = {"apple": 3, "banana": 1, "cherry": 2}
sorted_items = sorted(d.items(), key=lambda item: item[1]
-
闭包与延迟计算
funcs = [(lambda x=i: x) for i in range(3)]