Python-闭包和装饰器

补充:时间戳

import time
start_time = time.time()  #time.time()时间戳:从1970年1.1到现在的秒数
time.sleep(2)  #休眠两秒
end_time = time.time()
print(end_time - start_time) #结束时间减去开始时间等于运行时间

执行结果如下:

在这里插入图片描述

1. 闭包

在这里插入图片描述

1)函数里嵌套函数

def timeit():
    def wrapper():
        print('wrapper')
    print('timeit')

timeit()

打印timeit,只执行定义的内容
在这里插入图片描述

2)外部函数的返回值是内部函数的引用

def timeit():
    def wrapper():
        print('wrapper')
    print('timeit')
    return wrapper

in_fun = timeit()  #wrapper函数,in_fun实质上就是wrapper函数
in_fun()

执行结果如下:
在这里插入图片描述

3)内部函数可以使用外部函数的变量

def timeit(name):
    def wrapper():
        print('wrapper' + name) #name是外部函数的变量
    print('timeit')
    return wrapper

in_fun = timeit(name='westos')
in_fun()

执行结果如下:
在这里插入图片描述

2.装饰器

1、装饰器:用来装饰函数的工具。
2、在不改变源代码的情况下,添加额外功能(eg:计算运行时间,记录日志,权限判断)的工具。
3、如何实现装饰器?基于闭包。

在这里插入图片描述
在这里插入图片描述

import time
def timeit(f):   # f=add
    def wrapper(x,y):
        start = time.time()
        result = f(x,y)          #f实质上是add函数,是要装饰的函数
        end = time.time()
        print('函数运行时间为:%.4f' %(end - start))
        return result
    return wrapper
 
@timeit              # 语法糖,add=timeit(add)
def add(x,y):
    return x + y
result = add(1,3)
print(result)

执行结果如下:
在这里插入图片描述

3.万能装饰器

import time
from functools import wraps
def timeit(f):
    """计时器的装饰器"""
    @wraps(f)   ##保留被装饰函数的属性信息和帮助文档
    def wrapper(*args,**kwargs):      # 想接受任何参数可以用(*args,**kwargs)
        """wrapper内部函数""" 
        start = time.time()
        result = f(*args,**kwargs)
        end = time.time()
        print(f'函数{f.__name__}运行时间为{end - start}秒')
        return result
    return wrapper

@timeit
def login():
    """login desc"""
    print('login..........')
login()          #运行login,可以查看函数的运行时间
print(help(login))   #如果不用wraps,那么查看的就是wrapper内部函数的信息和帮助文档了

1)装饰器的万能模板

def 装饰器名称(f):
    def wrapper(*args,**kwargs):
        执行函数之前做的事情
        result = f(*args,**kwargs)
        执行函数之后做的事情
        return result
    return wrapper

利用做好的装饰器看一下爬一个图片需要多久:

import time
def timeit(f):
    def wrapper(*args,**kwargs):
        start = time.time()
        result = f(*args,**kwargs)
        end = time.time()
        print(f'函数{f.__name__}的执行时间为{end-start}')
        return result
    return wrapper

@timeit
def crawl():
    import requests
    url = 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.usefulstuff.io%2F2014%2F12%2Fpython_logo.jpg&refer=http%3A%2F%2Fcdn.usefulstuff.io&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1640430605&t=06e78c1a0f656346ca4fad75591e548b'
    content = requests.get(url).content
    with open('venv/python.png','wb') as f:   #图片,电影都是二进制文件,用wb
        f.write(content)
crawl()

执行结果如下:
在这里插入图片描述
得到了图片:
在这里插入图片描述

2)含参数的装饰器

import time
def timeit(args='seconds'):  ##传参
    def desc(f):
        def wrapper(*args,**kwargs):
            start = time.time()
            result = f(*args,**kwargs)
            end = time.time()
            if args == 'seconds':
                print(f'函数{f.__name__}的执行时间为{end-start}秒')
            elif args == 'minutes':
                print(f'函数{f.__name__}的执行时间为{(end-start)/60}分钟')
            return result
        return wrapper
    return desc

@timeit(args='seconds')
def login():
    print('login.....')

login()

3) 多装饰器

def is_login(f):
    def wrapper(*args,**kwargs):
        print('is_login,用户是否登录')
        result = f(*args,**kwargs)
        return result
    return wrapper

def is_permission(f):
    def wrapper(*args,**kwargs):
        print('is_permission,用户是否有权限')
        result = f(*args,**kwargs)
        return result
    return wrapper
##规则:执行装饰器内容是从上到下,而被装饰的内容是从下到上
@is_login
@is_permission
def show_hosts():
    print('显示所有云主机')

show_hosts()

执行结果如下,可以看到执行的内容是从上到下的:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值