Python 函数进阶


Python 函数进阶:从基础定义到闭包与装饰器

函数是 Python 编程的核心构建块。除了基本调用,Python 还提供了默认参数、可变参数、作用域控制、闭包、装饰器、递归等强大特性。本文通过一系列实用示例,系统讲解这些关键概念,助你写出更灵活、可维护的代码。


1. 基础函数定义与调用

def greet(name: str, age: int, gender: str, height: int):
    print(f'{name} is {age} years old, gender is {gender}, height is {height}')

greet('Jason', 18, 'female', 100)
greet('Jason', 18, gender='male', height=100)  # 关键字参数
  • 支持位置参数关键字参数混合使用;
  • 函数默认返回 None(即使没有 return)。

✅ 小技巧:使用关键字参数可提升代码可读性,尤其当参数较多时。


2. 函数返回值

def add(a: int, b: int) -> int:
    print(f'We got {a} and {b}')
    return a + b

print(f'Sum of 5 and 6 is {add(5, 6)}')  # 输出: Sum of 5 and 6 is 11
  • 使用 return 显式返回结果;
  • 类型提示(如 -> int)有助于静态检查(配合 mypy)。

3. 默认参数值

def greet(name: str, age: int, gender: str, height: int, msg='haha'):
    print(f'{name} is {age} years old, gender is {gender}, height is {height}')
    print(f'I want to say {msg}')

greet('Jason', 18, 'female', 100)                     # 使用默认 msg
greet('Jason', 18, gender='male', height=100, msg='hello')  # 覆盖默认值

⚠️ 注意:默认参数应为不可变对象(如 str, int, None),避免使用 []{},否则可能引发意外共享状态。


4. 可变参数:*args**kwargs

*args:接收任意数量的位置参数(元组)

def greet(*args):
    print(type(args))  # <class 'tuple'>
    print(args)        # ('jason', 'female', 18, 172)

greet('jason', 'female', 18, 172)

**kwargs:接收任意数量的关键字参数(字典)

def greet2(**kwargs):
    print(type(kwargs))  # <class 'dict'>
    print(kwargs)        # {'name': 'Jason', 'age': 18, 'gender': 'male'}

greet2(name='Jason', age=18, gender='male')

混合使用(顺序很重要!)

def greet3(name, *args, age=18, **kwargs):
    print(f'name is {name}, age is {age}')
    print('Extra args:', args)
    if 'f' in kwargs:
        print(kwargs)
    print('Gender:', kwargs.get('gender'))

greet3('Jason', 1, 'hello', age=18, gender='male')

📌 参数顺序规则:
def func(pos, *args, default=..., **kwargs)


5. 全局变量与作用域

n = 100

def test():
    n = 100      # 创建局部变量 n,不影响全局
    n += 1
    print(n)     # 101

test()
print(n)         # 100(全局未变)

def test2():
    global n     # 声明使用全局变量
    n += 1
    print(n)     # 101

test2()
print(n)         # 101(全局被修改)

✅ 修改全局变量必须使用 global 声明。


6. 递归:函数调用自身

基础递归(打印问候语)

def welcome(n):
    if n == 0:
        return
    print('你好啊')
    welcome(n - 1)

welcome(5)  # 打印 5 次

递归计算阶乘

def compute(n):
    if n == 1:
        return 1
    return n * compute(n - 1)

print(compute(5))  # 120

⚠️ 递归需有明确的终止条件,否则会导致栈溢出。


7. 递归优化:尾递归风格(模拟)

虽然 Python 不优化尾递归,但可通过累积参数改善可读性:

def fac(n, m=1):
    """计算 n!,m 为累积结果"""
    if n == 1:
        return m
    return fac(n - 1, n * m)

print(fac(3))  # 6
print(fac(4))  # 24
print(fac(5))  # 120

8. 闭包(Closure)

闭包指内部函数引用外部函数变量,即使外部函数已执行完毕:

def count(n: list):
    def add(m):
        n.append(m)
        return n
    return add

f_add = count([])
res = f_add(6)  # [6]
res = f_add(6)  # [6, 6]
print(res)      # [6, 6, 6, 6, 6]
  • add 函数“捕获”了外部变量 n
  • 即使 count() 已返回,n 仍可通过 f_add 访问和修改。

🔒 闭包常用于实现状态保持工厂函数装饰器等。


9. 装饰器(Decorator)

装饰器用于增强函数功能而不修改其源码:

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("pre")
        res = func(*args, **kwargs)
        print("post")
        return res
    return wrapper

@my_decorator
def add(n, m):
    return f'hello, {n + m}'

res = add(4, 5)
print(res)
# 输出:
# pre
# post
# hello, 9
  • @my_decorator 等价于 add = my_decorator(add)
  • 装饰器本质是高阶函数 + 闭包

10. for-else 结构

for 循环可搭配 else,仅在未被 break 中断时执行:

def is_sushu(n):
    for i in range(2, n):
        if n % i == 0:
            return False
    else:
        return True  # 注意:此处 else 属于 for,不是 if!

print(is_sushu(3))  # True

💡 更典型用法:

for item in items:
    if found(item):
        break
else:
    print("Not found!")

11. 深拷贝 vs 浅拷贝

浅拷贝(list.copy())只复制顶层引用

list1 = [1, 2, 3, [3, 4]]
list2 = list1.copy()
list2[-1][-1] = 9
print(list1)  # [1, 2, 3, [3, 9]] ← 内部列表也被修改!

深拷贝(copy.deepcopy)递归复制所有层级

import copy

list3 = copy.deepcopy(list1)
list3[-1][-1] = 10
print(list1)  # [1, 2, 3, [3, 9]] ← 不受影响
print(list3)  # [1, 2, 3, [3, 10]]

✅ 规则:

  • 若对象包含可变子对象(如 list、dict),需用 deepcopy
  • 否则 copy() 或切片 [:] 足够。

总结:函数核心特性速查表

特性 关键语法 用途
默认参数 def f(a, b=10): 提供常用默认值
可变参数 *args, **kwargs 接收任意参数
作用域 global 修改全局变量
递归 func(...) 调用自身 解决分治问题(如阶乘、树遍历)
闭包 内部函数引用外部变量 保持状态、延迟计算
装饰器 @decorator 增强函数(日志、权限、缓存等)
for-else for ...: ... else: ... 处理“未找到”场景
深拷贝 copy.deepcopy(obj) 完全独立复制嵌套对象

🐍 编程哲学
“Simple is better than complex.” —— 《The Zen of Python》
合理使用这些特性,让代码既强大又简洁。


希望这篇系统梳理能帮助你深入理解 Python 函数的高级用法!欢迎动手实践每个示例,并尝试组合不同特性(如“带装饰器的递归函数”)来加深理解。

本文由mdnice多平台发布

posted @ 2026-01-11 15:49  言下忘言  阅读(3)  评论(0)    收藏  举报