ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python装饰器详解

2020-12-06 13:05:59  阅读:147  来源: 互联网

标签:函数 python text2 text1 def time print 装饰 详解


@[pyhton装饰器详解]
需要了解装饰器,就先要了解什么是高阶函数,什么是函数嵌套。装饰器其实就是高阶函数和函数嵌套的综合应用。
顾名思义,装饰器,就是起一个装饰的作用的方案。既不改变函数源代码、也不改变函数的调用方式,起到增加新功能的作用
如何判断一个函数它是不是装饰器,依据标准就是:不改变函数源代码、不改变函数的调用方式,又来修饰原函数的作用

一、高阶函数

简单的来讲,高阶函数就是将函数和变量联想起来,也可以这样说,函数即变量。下面我们来演示以下一个普通高阶函数的实例。

def fun1():
    print("this is fun1")
    
def fun2():
    print("this is fun2")
    
def fun(fun1,fun2):
    fun1()
    fun2()
    
fun(fun1,fun2)

我们来看一下运行结果
在这里插入图片描述

fun(fun1,fun2)的作用就是将fun1、fun2作为一个实参传递给fun(),在fun()内部运行fun1()和fun2()
这就是一个非常简单的高阶函数的例子。

二、函数嵌套

函数嵌套就是在一个函数的函数体里又定义了函数,可以是一个,也可以是多个。下面来看一下函数嵌套的实例。

def fun1():
    print("this is fun1")
    def fun2():
        print("this is fun2")
        def fun3():
            print("this is fun3")

三、装饰器

此前说过,装饰器就是高阶函数和函数嵌套的综合应用。现在我们来看一个实例。

import time
def text1():
    time.sleep(3)
    print('in the text1')

def text2():
    time.sleep(3)
    print('in the text2')

text1()
text2()

运行结果:
在这里插入图片描述

此实例功能为调用text1()和text2(),在控制台上打印相应内容。如果想要给这两个函数新加一个功能,怎么办呢?这时候就要用到装饰器了。我们先来看代码:

import time

def timer(func):
    def deco():
        start_time=time.time()
        func()
        stop_time=time.time()
        print("the func run time is ",stop_time-start_time)
    return deco   

def text1():
    time.sleep(3)
    print('in the text1')

def text2():
    time.sleep(3)
    print('in the text2')

text1=timer(text1)
text1()
text2=timer(text2)
text2()

运行后发现
在这里插入图片描述
确实增加了一个函数功能(计算text1()和text2()的运行时间),是不是很神奇?既没有改变函数源代码、又没有改变函数调用方式,还增加了一个新功能。这就是装饰器的雏形,到底是怎么样实现的呢?再来看一下这个实例,是不是用到了函数嵌套还有高阶函数呢?如果还对函数嵌套还有高阶函数不了解的话,同志们可以去CSDN查看一下,在这里就不再多叙了。
再回过头来看看这段代码

text1=timer(text1)
text1()
text2=timer(text2)
text2()

要是有成千上万个函数需要装饰,是不是需要下面这样写呢

text3=timer(text3)
...

当然,你也可以这样写:

import time

def timer(func):
    def deco():
        start_time=time.time()
        func()
        stop_time=time.time()
        print("the func run time is ",stop_time-start_time)
    return deco
    
@timer#语法糖 text1=timer(text1)
def text1():
    time.sleep(3)
    print('in the text1')
       
@timer
def text2():
    time.sleep(3)
    print('in the text2')

text1()
text2()

来看一下运行结果:
在这里插入图片描述
是不是又很神奇?和上一个运行结果一样呀!!!
在这里我们用了语法糖:@timer,其作用和text1=timer(text1)相同。是不是减少了很多工作量呢?只要想给哪个函数增加功能,就在这个函数前边加上@timer。
先不要急着开心!但是遇到带参的函数呢?就像这样子:

@timer
def text2(name):
    time.sleep(3)
    print('in the text2',name)

这该怎么办呢?话不多说,先来看解决办法:

import time

def timer(func):
    def deco(*args,**kwargs):
        start_time=time.time()
        func(*args,**kwargs)
        stop_time=time.time()
        print("the func run time is ",stop_time-start_time)
    return deco
   
@timer#语法糖 text1=timer(text1)
def text1():
    time.sleep(3)
    print('in the text1')
      
@timer
def text2(name):
    time.sleep(3)
    print('in the text2',name)

text1()
text2('mumumax')

运行结果:
在这里插入图片描述
在这里,我们只需要将deco()传入参量,deco(*args,**kwargs)写法可以传多参,也可以不传参,是不是方便多了?
哈哈哈,是不是get一项新技能了呢?再接着get!!
在实际开发过程中,如某网站一个页面代表一个函数,现在需要给特定的一些页面来增添新功能(如增加用户验证),该怎么样实现呢?
先来看解决方法:

import time

user,passwd="mumumax","mumumax"

def auth(func):
    def wrapper(*args,**kwargs):
        usename=input("username:").strip()
        password=input("password:").strip()
        if usename==user and password==passwd:
            print("pass the yanzheng")
            res=func(*args,**kwargs)
        else:
            exit("验证失败")
        return res
    return wrapper
        
@auth
def index():
    print("welcome to index page")
     
@auth   
def home():
    print("welcome to home page")
    return "from home"
      
@auth    
def bbs():
    print("welcome to bbs page")   
    
index()
home()
bbs()

index()为首页,home()为登陆页,bbs()为其他页。来看运行结果:

在这里插入图片描述
当我输入的username和password与数据库中的相匹配时,我才可以访问index()、home()、bbs(),负责会“验证失败”。
python的基本解释器就讲解到这里,如果掌握了这些东西,99%的解释器原理你都已经掌握了,剩下的1%交给实战吧,如果对我的文章感兴趣,请为我点一个赞,如果有python的知识需要了解或探讨,可以加本人微信:cuiliang1666457052

标签:函数,python,text2,text1,def,time,print,装饰,详解
来源: https://blog.csdn.net/weixin_52134263/article/details/110732801

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有