Python学习-递归函数及装饰器函数

目录

一、递归函数

1、阶乘定义

 2、斐波那契数列

(1)递归实现

(2)使用循环

(3)使用字典记忆递归

 二、装饰器函数

1、装饰器的本质

2、使用@语法糖

2、带参装饰器

3、装饰器链

(1)基本语法

(2)示例代码

4、类装饰器

三、总结


一、递归函数

        递归函数是指函数在其内部调用自身的一种编程技巧,常用于处理具有重复结构或问题可分解为相同子问题的场景。

基本结构:

递归函数必须满足两个条件:

  1. 终止条件(base case)——防止无限递归;

  2. 递归调用(recursive case)——缩小问题规模

基本步骤:

  1. 定义递归函数:在函数体内调用函数自身。

  2. 设定终止条件:确保递归能终止。

  3. 逐步简化问题:通过传递较小的参数递归求解,直至终止条件满足。

1、阶乘定义

        阶乘是数学中一个基本概念,表示从 1n 的连续整数的乘积,记作:

n!=n×(n−1)×(n−2)×⋯×1

按照递归的思路,阶乘可以定义为:

  • 递归终止条件:当 n == 1 时,1! = 1

  • 递归调用关系n! = n * (n-1)!

def factorial(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n - 1)
print(factorial(5)) #结果为120

 2、斐波那契数列

        斐波那契数列是一种经典的递归数列,其定义如下:

F(0)=0        F(1)=1        F(n)=F(n−1)+F(n−2),n≥2

即:每一项等于前两项之和
数列前几项为:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

(1)递归实现

#递归实现
def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n - 1) + fib(n - 2)
print(fib(6)) #输出8

缺点:效率低,存在大量重复计算,时间复杂度是 O(2^n)

(2)使用循环

def fib_iter(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a
print(fib_iter(6)) #结果为8

优点:高效,无重复计算,时间复杂度 O(n)

(3)使用字典记忆递归

memo = {}
def fib_memo(n):
    if n in memo:
        return memo[n]
    if n < 2:
        result = n
    else:
        result = fib_memo(n-1) + fib_memo(n-2)
    memo[n] = result
    return result
print(fib_memo(10)) #结果为55

 二、装饰器函数

        装饰器函数是 Python 中的一种高级语法,用于在不修改原函数代码的前提下,动态地增强函数或类的功能

1、装饰器的本质

装饰器本质是一个返回函数的函数,通常用于“包装”另一个函数。

def decorator(func):        # 接收一个函数对象作为参数
    def wrapper():          # 定义一个包装函数,封装原函数逻辑
        print("开始执行")   # 执行前操作
        func()              # 调用原函数
        print("执行结束")   # 执行后操作
    return wrapper          # 返回包装函数

2、使用@语法糖

@decorator 是 Python 提供的一种简洁写法,等价于手动调用装饰器函数:

def decorator(func):        # 接收一个函数对象作为参数
    def wrapper():          # 定义一个包装函数,封装原函数逻辑
        print("开始执行")   # 执行前操作
        func()              # 调用原函数
        print("执行结束")   # 执行后操作
    return wrapper          # 返回包装函数

@decorator
def hello():
	print('hello')
hello()

结果为:

使用@语法糖等同于:

def func():
    ...
func = decorator(func)

语法糖优势:

  • 简洁:省去手动赋值

  • 清晰:一眼就知道哪个函数被装饰了

  • 常用于日志、权限控制、缓存等场景

2、带参装饰器

        带参装饰器是指:装饰器本身也接受参数,即 @装饰器(参数) 的形式。

这比普通装饰器多了一层函数结构,适用于需要动态控制装饰行为的场景,比如日志等级、重复次数、权限控制等

def outer_decorator(arg):         # 第1层:接收装饰器参数
    def decorator(func):          # 第2层:接收原函数
        def wrapper(*args, **kwargs):  # 第3层:包装原函数
            print(f"装饰器参数是:{arg}")
            return func(*args, **kwargs)
        return wrapper
    return decorator
@outer_decorator("日志模式")
def say_hello():
    print("Hello, Python!")

say_hello()

结果为:

可以对外层的参数进行定义进行循环输出的操作

def repeat(n):  # 外层:接收重复次数
    def decorator(func):  # 中层:接收被装饰函数
        def wrapper(*args, **kwargs):  # 内层:增强功能
            for i in range(n):
                print(f"第{i+1}次调用:", end="")
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat(3)
def greet(name):
    print(f"你好,{name}!")

greet("小明")

结果为:

3、装饰器链

        装饰器链是指:一个函数被多个装饰器依次包装,也叫多层装饰器
在 Python 中可以通过多个 @装饰器 叠加使用,每一层装饰器会依次包裹函数。

(1)基本语法

@dec1
@dec2
def func():
    ...

等同于

func = dec1(dec2(func))

执行顺序是从下往上包裹,运行时从外往里执行。

(2)示例代码

def decorator1(func):
    def wrapper(*args, **kwargs):
        print("装饰器1:开始")
        result = func(*args, **kwargs)
        print("装饰器1:结束")
        return result
    return wrapper

def decorator2(func):
    def wrapper(*args, **kwargs):
        print("装饰器2:开始")
        result = func(*args, **kwargs)
        print("装饰器2:结束")
        return result
    return wrapper

@decorator1
@decorator2
def say_hi():
    print("Hello!")

say_hi()

结果为:

总结执行流程:

  1. decorator1.wrapper 执行前打印 "装饰器1:开始"

  2. 调用 decorator2.wrapper,打印 "装饰器2:开始"

  3. 执行原函数 say_hi() → 打印 "Hello!"

  4. decorator2.wrapper 执行后打印 "装饰器2:结束"

  5. decorator1.wrapper 执行后打印 "装饰器1:结束"

4、类装饰器

        类装饰器是通过一个实现了 __call__ 方法的类来实现装饰器功能。它和函数装饰器作用相同:用于增强函数或方法功能,但使用的是类的方式组织逻辑

class MyDecorator:
    def __init__(self, func):
        self.func = func  # 接收被装饰的函数

    def __call__(self, *args, **kwargs):
        print("开始执行")
        result = self.func(*args, **kwargs)
        print("执行结束")
        return result

@MyDecorator
def say_hi():
    print("Hello, Python!")

say_hi()

结果为:

类装饰器和函数装饰器对比:

特点函数装饰器类装饰器
写法用函数定义用类定义,必须实现 __call__
可维护状态(属性)不方便可以轻松保存状态或计数
灵活性一般更强,可用属性/方法扩展

三、总结

        通过学习递归函数和装饰器函数,我深刻理解了函数式编程的强大与灵活。递归函数能优雅地解决分解类问题,如阶乘与斐波那契数列,提升了逻辑思维能力;装饰器函数则体现了Python语法的简洁与强大,可在不修改原函数的基础上增强功能,为开发提供了高效、优雅的扩展方式 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值