1. 参数深入理解
1.1 参数传递的内存机制
Python中参数传递的是内存地址(引用传递),而非值拷贝。这意味着:
- 可变对象(列表、字典)在函数内修改会影响外部变量。
- 不可变对象(数字、字符串)在函数内重新赋值会创建新对象。
def modify_list(lst):
lst.append(4) # 修改原列表
my_list = [1, 2, 3]
modify_list(my_list)
print(my_list) # 输出:[1, 2, 3, 4]
def reassign_str(s):
s = "新字符串" # 创建新对象
my_str = "原字符串"
reassign_str(my_str)
print(my_str) # 输出:原字符串
1.2 默认参数的陷阱
当默认参数为可变对象时,多次调用会共享同一内存地址:
def buggy_func(data=[]):
data.append(1)
return data
print(buggy_func()) # [1]
print(buggy_func()) # [1, 1](非预期结果)
解决方案:使用不可变类型(如None)作为默认值,并在函数内创建新对象:
def fixed_func(data=None):
data = data or []
data.append(1)
return data
1.3 动态参数(*args与**kwargs)
- *args:接收任意数量的位置参数,存储为元组。
- **kwargs:接收任意数量的关键字参数,存储为字典。
def dynamic_args(*args, **kwargs):
print(f"位置参数: {args}")
print(f"关键字参数: {kwargs}")
dynamic_args(1, 2, name="Alex", age=18)
# 输出:
# 位置参数: (1, 2)
# 关键字参数: {'name': 'Alex', 'age': 18}
应用场景:格式化字符串、批量处理数据:
values = [11, 22, 33]
print("和为:", *values) # 解包为 print("和为:", 11, 22, 33)
2. 函数名的本质与使用
2.1 函数名作为变量
函数名本质是一个指向函数对象的变量:
def greet():
print("Hello!")
alias = greet
alias() # 输出:Hello!
2.2 函数作为参数与返回值
函数作为参数:
def apply(func, x, y):
return func(x, y)
result = apply(lambda a, b: a * b, 3, 4)
print(result) # 输出:12
函数作为返回值:
def multiplier(factor):
def inner(x):
return x * factor
return inner
double = multiplier(2)
print(double(5)) # 输出:10
2.3 高阶函数应用
-
map:对可迭代对象应用函数:
numbers = [1, 2, 3] squared = list(map(lambda x: x**2, numbers)) # [1, 4, 9]
-
filter:过滤元素:
even = list(filter(lambda x: x % 2 == 0, numbers)) # [2]