闭包函数及装饰器

闭包函数及装饰器

一、闭包函数

1.1 函数传参的方式一

def func(x):
    print(x)

func(1)
func(1)
func(1)
-------------------------------------------------------------
1
1
1

1.2 函数传参的方式二

闭包函数,把变量和函数一起包起来,下次要用直接调用

#这样传就不会每一次传参的时候都输入
def outter(x):
    x = 1

    def inner():
        print(x)
    return inner

f = outter(1)
f()
f()
f()
---------------------------------------------------------
1
1
1

让我们再看一个利用闭包函数爬取网站的例子吧!

import requests

def func(url):
    def get_res():
        response = requests.get(url)
        print({url})
    return get_res

baidu = func('https://www.baidu.com')

baidu()
baidu()
-----------------------------------------------------------
{'https://www.baidu.com'}
{'https://www.baidu.com'}

二、装饰器

2.1 什么是装饰器

装饰器:装饰的工具(函数),这个函数有装饰的作用

装饰器本质就是一个函数A,装饰的对象也是一个函数B,用一个函数A去装饰一个函数B

2.2 装饰器遵循的原则

  1. 不改变函数B的调用方式

  2. 不改变函数B的源代码

def A():
    """装饰器"""
    pass

def B():
    """被装饰的对象"""
    pass
B()

2.3 装饰器举例

打印函数运行的时间

# 2.3.1 改变了函数体代码,没改变调用方式(不是装饰器,没有遵循装饰器原则)
import time

def index():
    start = time.time()
    print('您好')
    time.sleep(1)
    end = time.time()
    print(end-start)
    
index()
----------------------------------------------------------
您好
1.0013189315795898
# 2.3.2 没改变调用方式,也没改变源码,但是不通用(不是装饰器,没有遵循装饰器原则)
import time 
def index():
    '''被装饰的函数'''
    print('hello')
def index1():
    print('hello1')
    
    start = time.time()
    index()
    time.sleep(1)
    end = time.time()
    print(end-start)
    
    start = time.time()
    index1()
    time.sleep(1)
    end = time.time()
    print(end-start)
-----------------------------------------------------------
hello
1.0003104209899902
hello1
1.000321388244629
#每次调用的时候都得运行一遍,真的很麻烦
# 2.3.3  真正的装饰器
import time
def index():
    print('您好啊!')
    time.sleep(1)

def deco(func):    # func = 真正的index
    '''装饰器'''
    def f1():    #重新创建的index
        start = time.time()
        func()      #真正的index
        end = time.time()
        print(end-start)
    return f1

index = deco(index)
index()     #f1

2.4 三层装饰器

#利用装饰器写一个装饰器
def auth(engine):
    def login(func):
        def inner(*args,**kwargs):
            #登录功能
            if engine =='file':
                username = input('username:')
                pwd = input('pwd:')
                if username =='jiayi'and pwd =='123':
                    print('登录成功')
                    res = func(*args,**kwargs)  #shopping()

                    print('登录失败')

            elif engine =='db':
                print('账号来自于数据库,非法请求')

        return inner
    return login
@auth('db')
def shopping():
    print('shopping')
shopping()
-------------------------------------------------------------------------
账号来自于数据库,非法请求

2.5 装饰器模板

2.5.1 双层装饰器

def outter(func):
    def wrapper(*args.**kwargs):  #wrapper是未来要运行的函数
        #加功能
        res = func(*args,**kwargs)  #func是被装饰的函数
        return res
    return wrapper
@outter
def shopping():
    print('shopping')

2.5.2 三层装饰器

# 三层装饰器:给双层装饰器加参数
def sanceng (engine):
    def outter(func):
        def wrapper(*args,**kwargs):  # wrapper是未来要运行的函数
            #加功能
            print(engine)
            res = func(*args,**kwargs)  #func是被装饰的函数
            return  res
        return wrapper
    return outter

@sanceng('db')
def shopping():
    print('shopping')
posted @ 2019-08-12 15:29  JIAYIYAN  阅读(132)  评论(0编辑  收藏  举报