Python装饰器

什么是装饰器?

官方解释:
装饰器是用来管理和调用函数和类的一个可调用对象,也就是说分为函数装饰器和类装饰器;
但是看完之后,我并不能明白装饰器的含义!!所以我在网上进行了查找,觉得下面的这个解释很通俗,引用于

https://m.php.cn/article/424884.html

装饰器就是对被装饰的对象(函数、类)进行重构的,其可以在不改变原来对象的情况下调用对象时执行重构后的行为。
这里也引用作者得python代码:

def decorator(f):
    def wrapper(x,y):
        return x+y
    return wrapper
@decorator
def func(x,y):
    return 1
func(3,4)

我把这句话分为了三层意思进行理解:
1、装饰器:我们的装饰函数;
2、被装饰对象:引用装饰器的函数或类(类的概念现在还没有学到);
3、返回得可调用对象:装饰器得内嵌函数;
4、重构:(对对象进行重构)
原文作者有提到这样一句话,讲的是****装饰器本身接受被装饰的对象,装饰器返回的可调用对象接受被装饰对象的所有参数。

在上面那一段代码中,
装饰器是: decorator
返回的可调用对象是: wrapper
被装饰的对象是 :func

当调用func(3,4)的时候发生了什么?
此时:返回的可调用对象(wrapper)给了func,你也可以理解为现在的func的代码是
def func(x,y)
		return x+y
装饰器的练习

在这里插入图片描述
timeit 是一个函数,它接受一个参数,这个参数必须是函数(或者说可调用对象或者说是被修饰的函数),并且 timeit 的返回结果一定是一个函数。

带参装饰器

参数分为形式参和实参,带参装饰器其实就是说我们的装饰器中的函数是带有参数的,如果我们在调用函数的时候不手动赋值,那么参数就是使用的默认值,如果手动赋值,那么参数的结果就是我们自己的手动赋值;
引入菜鸟教程的例子:
地址:
https://www.runoob.com/w3cnote/python-func-decorators.html

from functools import wraps


def logit(logfile='out.log'):
    def logging_decorator(func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
            log_string = func.__name__ + " was called"
            print(log_string)
            # 打开logfile,并写入内容
            with open(logfile, 'a') as opened_file:
                # 现在将日志打到指定的logfile
                opened_file.write(log_string + '\n')
            return func(*args, **kwargs)

        return wrapped_function

    return logging_decorator
@logit()
def myfunc1():
    pass
myfunc1()

# Output: myfunc1 was called
# 现在一个叫做 out.log 的文件出现了,里面的内容就是上面的字符串

@logit(logfile='func2.log')
def myfunc2():
    pass
myfunc2()
# Output: myfunc2 was called
# 现在一个叫做 func2.log 的文件出现了,里面的内容就是上面的字符串

保留被装饰函数的函数名字和帮助文档信息在装

饰器函数的下面(闭合函数的上面加:@functools.wraps(fun))

import functools
import random
import string
import time
li = [random.choice(string.ascii_letters) for i in range(100)]
print(time.time()) #打印处自1970年到现在一共多少秒
def timeit(fun):
    # @functools.wraps(fun)
    def wrapper(*args,**kwargs): #接收可变参数 和 关键字参数
        """这是一个装饰器timeit"""
        # 在函数执行之前
        start_time = time.time()
        # 执行函数
        res = fun(*args,**kwargs)
        # 在函数执行之后
        end_time = time.time()
        print('运行时间为:%.6f' %(end_time - start_time))
        return res
    return wrapper
@timeit
def con_add():
    """这是一个con_add"""
    s = ''
    for i in li:
        s +=i
    print(s)
con_add()
print(con_add.__name__)
print(con_add.__doc__)

在这里插入图片描述
如果不加@functools.wraps(fun),则显示的是装饰器的信息
在这里插入图片描述

多个装饰器

多个装饰器装饰函数 从上到下去执行的

def decorator_a(fun):
    def inner_a(*args,**kwargs): #接收可变参数和关键字参数
        print('Get in inner_a')
        fun(*args,**kwargs)
    return inner_a

def decorator_b(fun):
    def inner_b(*args,**kwargs):
        print('Get in inner_b')
        fun(*args,**kwargs)
    return inner_b
 #多个装饰器装饰函数 从上到下去执行的
@decorator_a
@decorator_b
def f(x):
    print('Gat in f')
f(1)

在这里插入图片描述

装饰器的应用

多个装饰器的应用场景
会采用多个装饰器先验证是否登陆成功 再验证权限是否足够

import inspect
login_session = ['root','admin','redhat']
import functools
def is_login(fun):
    @functools.wraps(fun)
    def warapper(*args,**kwargs):#('root',)如果有多个可变参数,args会存成元组
        print(args)
        if args[0] in login_session:
            temp = fun(*args,**kwargs)
            return temp
        else:
            print()
            print('Error:%s 没有登陆成功' %(args[0]))
    return warapper
def is_admin(fun):
    @functools.wraps(fun)
    #inspect_res 会返回一个字典
    # key:形参 value:对应的实参
    def wrapper(*args,**kwargs):
        inspect_res = inspect.getcallargs(fun,*args,**kwargs)
        print('inspect的返回值是:%s' %(inspect_res))
        if inspect_res.get('name') == 'root':
            temp = fun(*args,**kwargs)
            return temp
        else:
            print('not root user,no permisson add user')
    return wrapper
@is_login
@is_admin
def adduser(name):
    print('add_user')
adduser('refhat')

在这里插入图片描述

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值