学习Python第9天_装饰器&函数递归

本文介绍了Python中的装饰器和函数递归。装饰器允许在不修改原函数的基础上添加新功能,有利于团队开发中的代码复用和简化。文章探讨了简单装饰器的实现以及多个装饰器的叠加应用。而函数递归虽然能解决某些问题,但应谨慎使用,因为过度递归可能导致内存消耗过大。理解递归的关键在于找到临界条件和相邻递归的关系,并可能形成递归公式。
摘要由CSDN通过智能技术生成

仅记录个人学习Python所学,学识浅薄,若有错误欢迎指出。文章可能会不太完善,后续可能会继续更新。

一、装饰器

在代码运行期间,可以动态增加函数功能的方式,被称为装饰器【Decorator】

也就是说,在不修改原函数的基础上,给原函数增加功能

好处:在团队开发中,如果两个或者两个以上的程序员会用到相同的功能,但是功能又有细微的差别,采用装饰器:相互不影响,代码简化
简单装饰器
使用@+函数名       调用装饰器

# 装饰器
# 作用: 在不修改原函数的情况下,在函数调用之前和之后添加装饰(功能)


def eat():
    print('吃饭')


def run():
    print('跑步')


# def eat2():
#     print('吃饭之前跳个舞')
#     # eat()
#     run()
#     print('吃饭后唱歌')


def outer(fun):
    print('先跳个舞')
    fun()
    print('再唱歌')


outer(eat)
print('*'*150)

# 简单装饰器


def outer2(fun):
    def inner():
        print('先跳个舞')
        fun()
        print('再唱歌')
    return inner 


@outer2
def eat2():
    print('吃饭2')

外部函数需返回内部函数,但不要带(),带上()就是调用内部函数,会产生返回值,之前有提到过函数名是指向函数的变量。
若不返回内部函数,则内部函数没有被定义无法调用。

# 使用装饰器 : 原理
eat2 = outer2(eat2)
# eat2()
# print(eat2.__name__)

# 3.写一个装饰器来统计函数运行的时间
# 装饰器
import time


def outer3(fun):
    # print(fun.__name__)   # show
    def inner():
        s = time.time()
        fun()
        e = time.time()
        print(e - s)
    return inner


@outer3
# @outer3 < = > show = outer3(show)
def show():
    for i in range(10000000):
        pass


# s = time.time()     # 当前时间,时间戳(秒) 时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量
# print(s)
show()

# e = time.time()
# print(e-s)

通用装饰器

# 通用装饰器


def outer(fun):
    def inner(*args, **kwargs):
        print('before')
        res = fun(*args, **kwargs)
        print('after')
        return res

    return inner


@outer
def eat():
    print('吃饭')


@outer
def sing(song):
    print('吴亦凡唱:', song)
    return '唱得好!'


# 调用


eat()
print()
result = sing('大碗宽面')
print(result)

多个装饰器作用于一个函数

# 装饰器的使用
def outer(fun):
    def inner(a):
        if a < 0:
            a = abs(a)
        fun(a)

    return inner


@outer
def set_age(n):
    print('n:', n)


set_age(-5)


# 在一个函数上使用多个装饰器
def outer1(f):
    def inner():
        print('before1')
        f()
        print('after1')

    return inner


def outer2(f):
    def inner():
        print('before2')
        f()
        print('after2')

    return inner


@outer1
@outer2
def sing():
    print('唱歌')


sing()
"""
    before1
    before2
    唱歌
    after2
    after1
"""

第一个装饰器调用完成,第二个装饰器才可以调用完

二、函数递归

尽量少用递归 过多递归调用可能会占用过多内存

递归函数:一个会调用自身的函数【在一个函数的内部,自己调用自己】

递归调用

递归中包含了一种隐式的循环,他会重复指定某段代码【函数体】,但这种循环不需要条件控制

使用递归解决问题思路:

​ a.找到一个临界条件【临界值】

​ b.找到相邻两次循环之间的关系

​ c.一般情况下,会找到一个规律【公式】

# 函数递归: 函数内部调用自身
"""
5!  = 5 * 4!
    = 5 * 4 * 3!
    = 5 * 4 * 3 * 2!
    = 5 * 4 * 3 * 2 * 1!
"""


# 使用递归:
#       1.找到公式,如:f(n) = n * f(n - 1)
#       2.找临界值,如:n = 1 ,f(1) = 1
#       3. 一定要相信函数可以实现

# 求 n 的阶乘


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


print(fn(5))


# 1.封装函数,传入n,得到 第n个 斐波那契数
#  	    1 1 2 3 5 8 13 21
# 找公式:f(n) = f(n-1) + f(n-2)
# 找临界值:n = 1, 2; f(1) = f(2) = 1


def f(n):
    if n <= 2:
        return 1
    return f(n - 1) + f(n - 2)


print(f(10))


# 2.封装函数,传入n,得到 前n个 斐波那契数
#  	    1 1 2 3 5 8 13 21


def f2(n):
    for i in range(1, n + 1):
        print(f(i), end=" ")
    print()


f2(10)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值