美文网首页
Python基础 装饰器

Python基础 装饰器

作者: 态度哥 | 来源:发表于2019-12-20 10:31 被阅读0次

装饰器

python装饰器个人的理解: 在原本函数基础上,在不改变原函数名和原函数代码的情况下,增加对这个函数的的拓展,本身也是函数. 特点就是返回值也是一个函数,这个函数就是被修饰的函数(当然他是包了一层).(比如: 函数A , B函数是A函数的装饰器,B的返回值其实就是A函数,不过是在执行A函数之前做了一些事'比如是否登录'和执行A函数之后做了一些事'比如记录登录的人员信息') 下面是的一个装饰器大概的样子:

def 装饰器的名字(func):  #func被装饰的函数
    def inner(*args,**kwargs):   # *args,**kwargs 为参数可有可无或普通参数,看使用场景
        '''在执行被装饰的函数之前要做的事儿'''
        '''判断是否登录'''
        ret = func(*args,**kwargs)
        '''在执行被装饰的函数之后要做的事儿'''
        '''写log'''
        return ret  # 返回值可有可无,看使用场景
    return inner

什么情况下会使用装饰器

一般情况在已经写好发版的程序的基础上,需要对一个函数执行前后增加功能的时候
开放封闭原则:
开放 :对扩展是开放的
封闭 :对修改是封闭

例子: 我这里有个论坛的三个页面比如:文章、日记、评论,我需要在进入前判断下用户是否登录,没有登录先去登录,登录之后直接进入页面,并把事件上传到服务器

import time
def za_loginWraps(func):
    '''
    登录装饰器
    :param func:
    :return:
    '''
    def inner(*args,**kargs):
        #判断登录与否的逻辑
        ret = func(*args,**kargs)
        #写入文件,并上传服务器
        return ret
    return inner

@za_loginWraps
def za_article():
    '''
    文章详情
    :return:
    '''
    print('欢迎 *** 用户访问 文章 页面')

@za_loginWraps
def za_diary():
    '''
    日记详情
    :return:
    '''
    print('欢迎 ***  用户访问 日记 页面')

@za_loginWraps
def za_comment():
    '''
    评论详情
    :return:
    '''
    print('欢迎  用户访问 评论 页面')

文章、日记、评论三个函数在执行前都被za_loginWraps装饰器装饰
了,所有会先执行装饰器的代码.

@za_loginWraps这句话就代表装饰下面的函数了.等价于: za_comment = za_loginWraps(za_comment)

za_loginWraps是一个函数,参数也是一个函数,返回值也是一个函数.(参数和返回值就是被装饰的函数)
za_article``````za_diary``````za_comment这三个函数就相当于在不改变原函数代码和名字的前提下被注入了是否登录功能,现在只要调用这三个函数,它就变成了先去执行装饰器然后再去执行原函数,原函数不会被重复执行.

一个简单的装饰器就完事了.

扩展:

这个时候你去打印下 文章、日记、评论的 函数名字你会发现是一样的.

print([za_comment.__name__])
print([za_article.__name__])
print([za_diary.__name__])

['inner']
['inner']
['inner']

出现这情况是因为,·@za_loginWraps这句话等于 za_comment = za_loginWraps(za_comment). 把被装饰的函数,传到装饰器中,装饰器最后返回的是 里面的函数inner方法,所有这里其实是 inner函数的内存地址.
想打印原方法名称可以引用: from functools import wraps在装饰器中加入:
@wraps(func)代码变为:

from functools import wraps
import time

def za_loginWraps(func):
    '''
    登录装饰器
    :param func:
    :return:
    '''
    @wraps(func)
    def inner(*args,**kargs):
        #判断登录与否的逻辑
        ret = func(*args,**kargs)
        #写入文件,并上传服务器
        return ret
    return inner

这个时候再去打印三个函数名就变为:

['za_comment']
['za_article']
['za_diary']

传递参数

因为参数会有很多种,一般把参数都写成*args,**kwargs这样为了能够适配所有参数类型.(当时参数类型简单的话,可以直接去写.) 比如我要在详情页面传递用户名

from functools import wraps
import time

def za_loginWraps(func):
    '''
    登录装饰器
    :param func:
    :return:
    '''
    @wraps(func)
    def inner(*args,**kargs):
        #打印传递过来的用户名
        print(args[0])#参数如果传递就如何获取
        ret = func(*args,**kargs)
        #写入文件,并上传服务器
        return ret
    return inner

@za_loginWraps   # za_comment = za_loginWraps(za_comment(username))
def za_comment(username):
    '''
    评论详情
    :return:
    '''
    print('欢迎 %s  用户访问 评论 页面'%username)

多个装饰器修饰一个函数

有的时候一个装饰器代表一个功能,比如现在我要在文章函数执行前加上是否登录和统计页面的使用时长,这个时候我加一个装饰器代码如下:

def login(func):
    print('----正在装饰01----')
    def inner():
        print('----正在执行01----')
        func()
        print('----执行后01----')
    return inner

def time(func):
    print('----正在装饰02----')
    def inner():
        print('----正在执行02----')
        func()
        print('----执行后02----')
    return inner


@login
@time
def func():
    '''
    文章详情
    :return:
    '''
    print('欢迎 *** 用户访问 文章 页面')

func()

func函数上面有两个装饰器了,执行代码结果如下:

----正在装饰02----
----正在装饰01----
----正在执行01----
----正在执行02----
欢迎 *** 用户访问 文章 页面
----执行后02----
----执行后01----

来分析下:
看执行结果得知装饰器先走的离函数进的,但是执行的时候是由上往下的.所以得出: 装饰是从下往上,调用是从上往下
再看下执行开始和结束: 先说一下

@login
@time   
def func():
      *****    

等价于:
func = login(time(func()))

.......未完......

相关文章

  • python 基础 07 装饰器

    python 基础 07 1. 装饰器

  • Day04 - Python基础4

    Day04的课程要点记录详细教程地址:Day4 - Python基础4 | python装饰器 一、装饰器 1.1...

  • 装饰器五部曲

    听说你学不会装饰器?Python基础之装饰器五部曲,带你轻轻松松学会装饰器 装饰器(decorator)是Pyth...

  • Python装饰器(Decorator)完全指南-进阶篇

    Decorator进阶指南 在[python装饰器完全指南基础篇中],我们已经知道了python中的装饰器本质上只...

  • Python装饰器学习

    Python装饰器学习 Python装饰器学习(九步入门)基础部分根据此文来学习的,接下来将根据此文内容进行整理,...

  • python基础-装饰器

    记录自己学习py基础的点点滴滴 装饰器 由浅入深,先定义一个函数,把这个函数赋值给一个变量,然后可以通过变量直接调...

  • Python基础 装饰器

    装饰器 python装饰器个人的理解: 在原本函数基础上,在不改变原函数名和原函数代码的情况下,增加对这个函数的的...

  • python (类/函数)对一个函数应用多个装饰器 执行过程

    网上很多讲解单个python 装饰器的文章,基础知识我们简单描述。 首先了解装饰器是用来干什么的,装饰器可以增加函...

  • 装饰器模式

    介绍 在python装饰器学习 这篇文章中,介绍了python 中的装饰器,python内置了对装饰器的支持。面向...

  • python学习线路

    阶段一:基础阶段Python语言基础 · 环境搭建与配置· 变量和数据类型· 编程基础· 装饰器· gui介绍简易...

网友评论

      本文标题:Python基础 装饰器

      本文链接:https://www.haomeiwen.com/subject/xlmbnctx.html