博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python装饰器与递归函数
阅读量:6158 次
发布时间:2019-06-21

本文共 5420 字,大约阅读时间需要 18 分钟。

装饰器

1.开放封闭原则

软件面世时,不可能把所有的功能都设计好,当前的未来一两年功能给你上线,定期更新迭代。对于软件之前的写的源代码一般都不会修改,对函数里面的代码以及函数的调用方式。

封闭原则: 不要改变源码。

开放原则:更新增加一些额外的功能。

python中装饰器:完美的诠释的开放封闭原则。

装饰器就是一个函数: 他要装饰一个函数,在不改变原函数的源码以及调用方式的前提下,给其增加一个额外的功能。

2.初识装饰器

# 装饰器函数def test_time(x):  # x = index    def inner():        start_time = time.time()        x()        end_time = time.time()        print(f'此函数的执行效率{end_time-start_time}')    return inner@test_time  #与在下面写 index = test_time(index) 效果一样def index():    time.sleep(2)    print('欢迎访问博客园首页')# index = test_time(index) # 运行效果 index = innerindex() # 此时 index() 在执行 inner 函数@test_timedef func1():    time.sleep(2)    print('欢迎访问日记首页')@test_timedef func2():    time.sleep(1)    print('欢迎访问评论首页')# func1 = test_time(func1)  #麻烦 每个函数下面都要改函数名 推荐用@# func1 = test_time(func1)func1()func2()

3.被装饰函数带返回值

def test_time(x):  # x = index    def inner():        start_time = time.time()        ret = x()        end_time = time.time()        print(f'此函数的执行效率{end_time-start_time}')        return ret # 返回index() 的返回值给 inner()    return inner@test_time  # index = test_time(index)def index():    time.sleep(0.5)    print('欢迎访问博客园首页')    return Trueprint(index())  # inner()# 你应该是让True返回给index()这样才完美了,但是现在index是inner,所以你要是完全不改变原函数的使用,# 你print(index()) ---> True

4.被装饰函数带参数

# 被装饰函数带参数,无论加不加装饰器,你的实参都应该传给形参。# 但以上的版本不能实现传参,index('太白金星') == inner('太白金星')def test_time(x):  # x = index    def inner(*args,**kwargs):        # 函数的定义:* ** 聚合。        # args = ('苹果',)        #args = (1, 3)        start_time = time.time()        ret = x(*args,**kwargs)        # 函数的执行:* ** 打散。        # ret = x(*('苹果',))  ==x('苹果')        # ret = x(*(1, 3))  ==x(1,3)        end_time = time.time()        print(f'此函数的执行效率{end_time-start_time}')        return ret    return inner@test_time  # index = test_time(index)def index(n):    time.sleep(0.5)    print(f'欢迎{n}访问博客园首页')    return True@test_time  # index = test_time(index)def func2(a,b):    time.sleep(0.5)    print(f'最终结果:{a+b}')    return a + bprint(index('苹果'))  # inner('苹果')print(func2(1,3)) # == inner(1,3)

5.标准版装饰器

def warpper(f): # 标准装饰器模板    def inner(*args,**kwargs):        '''被装饰函数之前的操作'''        # print(666)        ret = f(*args,**kwargs)        '''被装饰函数之后的操作'''        # print('执行完毕了')        return ret    return inner@warpper # 调用def func():    print(111)

6.带参数的装饰器

def wrapper_out(n,*args,sex='男',):    def wrapper(f):  # f = func1        def inner(*args,**kwargs):            ret = f(*args,**kwargs)  # func1()            return ret        return inner    return wrapperdef func1():    print('in func1')func = wrapper_out(1)  # 返回值是wrapper函数名ly = func(func1)  # 等于wrapper(func1) = inner 返回值ly()  # 等于inner()# 使两个函数通过装饰器传参打开两个不同的文件def wrapper_out(n):    def wrapper(f):        def inner(*args,**kwargs):            username = input('请输入用户名:').strip()            password = input('请输入密码:').strip()            with open(n,encoding='utf-8') as f1:                for line in f1:                    user,pwd = line.strip().split('|')                    if username == user and password == pwd:                        print('登陆成功')                        ret = f(*args,**kwargs)                        return ret                return False        return inner    return wrapper"""@wrapper_out('qq')def qq():    print('成功访问qq')qq()看到带参数的装饰器分两步执行:@wrapper_out('腾讯')    1. 执行wrapper_out('腾讯') 这个函数,把相应的参数'腾讯' 传给 n,并且得到返回值 wrapper函数名。    2. 将@与wrapper结合,得到我们之前熟悉的标准版的装饰器按照装饰器的执行流程执行。"""@wrapper_out('qq')def qq():    print('成功访问qq')@wrapper_out('tiktok')def tiktok():    print('成功访问抖音')qq()tiktok()# 开发思路:增强耦合性

7.多个装饰器装饰一个函数

def wrapper1(func1):  # func1 = f原函数    def inner1():        print('wrapper1 ,before func')  # 2        func1()        print('wrapper1 ,after func')  # 4    return inner1def wrapper2(func2):  # func2 == inner1    def inner2():        print('wrapper2 ,before func')  # 1        func2()  # inner1        print('wrapper2 ,after func')  # 5    return inner2@wrapper2  # f = wrapper2(f) 里面的f == inner1  外面的f == inner2@wrapper1  # f = wrapper1(f) 里面的f == func1  外面的 f == inner1def f():    print('in f')  # 3f()  # inner2()# 从上往下执行函数前的操作,从下往上执行函数后的操作,中间执行函数

递归函数

递归函数:函数或者其他代码都可以解决递归解决的问题,但是递归在某些时候能出奇制胜的效果

通俗点说,就是函数在自己内部调用自己。

递归函数举例

# 初识递归。def func(n):    print(n)    n += 1    func(n)func(1)# 官网规定:默认递归的最大深度1000次。# 如果你递归超过100次还没有解决这个问题,那么执意使用递归,效率很低。'''下边的每一个人都比上一个大两岁,计算第四个人的年龄1  太白   182  景女神  18 + 23  宝元    18 + 2 + 24  alex    18 + 2+ 2+2  age(4) = age(3) + 2'''def age(n):    if n == 1:        return 18    else:        return age(n-1) + 2print(age(4))'''递归内部运算def age(4):    if n == 1:        return 18    else:        return age(3) + 2age(4) = age(3)  + 2def age(3):    if n == 1:        return 18    else:        return age(2) + 2age(4) = age(2) + 2  + 2def age(2):    if n == 1:        return 18    else:        return age(1) + 2age(4) = age(1) + 2 + 2  + 2    def age(1):    if n == 1:        return 18    else:        return age(1) + 2age(4) = 18 + 2 + 2  + 2    '''l1 = [1, 3, 5, ['太白','元宝', 34,],66]# 将l1以下面的形式展现在屏幕上'''135'太白''元宝'3466'''l1 = [1, 3, 5, ['太白','元宝', 34,],66]# 利用双层for循环for i in l1:    if type(i) == list:        for j in i:            print(j)    else:        print(i)# 但如果列表嵌套的层数比较多,需要多层for循环,代码重复性高,这时就可以用递归# 递归函数def func(alist):    for i in alist:        if type(i) == list:            func(i)  # func(['太白','元宝',34])        else:            print(i)func(l1)# 这样无论列表嵌套多少层,这个函数都能解决

转载于:https://www.cnblogs.com/changyifei-8/p/11078137.html

你可能感兴趣的文章
【SICP练习】150 练习4.6
查看>>
HTTP缓存应用
查看>>
KubeEdge向左,K3S向右
查看>>
DTCC2013:基于网络监听数据库安全审计
查看>>
CCNA考试要点大搜集(二)
查看>>
ajax查询数据库时数据无法更新的问题
查看>>
Kickstart 无人职守安装,终于搞定了。
查看>>
linux开源万岁
查看>>
linux/CentOS6忘记root密码解决办法
查看>>
25个常用的Linux iptables规则
查看>>
集中管理系统--puppet
查看>>
分布式事务最终一致性常用方案
查看>>
Exchange 2013 PowerShell配置文件
查看>>
JavaAPI详解系列(1):String类(1)
查看>>
HTML条件注释判断IE<!--[if IE]><!--[if lt IE 9]>
查看>>
发布和逸出-构造过程中使this引用逸出
查看>>
使用SanLock建立简单的HA服务
查看>>
Subversion使用Redmine帐户验证简单应用、高级应用以及优化
查看>>
Javascript Ajax 异步请求
查看>>
DBCP连接池
查看>>