闭包函数与装饰器

 

一、闭包函数

闭包函数:把闭包函数内部的变量+闭包函数内部的函数两者包裹在一起,然后通过返回值的形式返回出来

import requests

def outter(url):  #闭包函数
    def get():
        res = requests.get(url)
        print(f'获取{url}的数据')
    return get  #函数对象

baidu = outter('http://www.baidu.com')
python = outter('http://www.python.org')

baidu()
baidu()

python()
python()
打印结果为:获取https://www.baidu.com的数据
    获取https://www.baidu.com的数据
      获取https://www.python.org的数据
获取https://www.python.org的数据

 

def f1(a):
    def f2():
        pass
    return f2

res = f1(a = 1)
res()

 

二、装饰器

装饰器指的是为被装饰器对象添加额外功能

装饰器注意点:

  1.装饰器本身是函数,只不过是又用发来装饰被装饰的函数

  2.装饰器不改变被装饰函数的源代码

  3.装饰器不改变被装饰对象的调用方式

二层装饰器模板:

def dec(fun):
    def wrapper(*args,**kwargs)
        #要加什么功能就加上去
        res = fun(*args,**kwargs)
        return res
    return wrapper

 

1.无参装饰器

def index():
    '''被装饰的函数'''
    print('index')
    time.sleep(1)

def time_count(fun): #fun才是真正的index
    '''装饰器'''
    def wrapper():
        start = time.time()
        fun()
        end = time.time()
        print(end-start)
    return wrapper

index = time_count(index)
index()
打印结果为:index
          1.0000267028808594     

2.带返回值

import time

def index():
    '''被装饰过的函数'''
    print('index')
    return 123

def time_count(fun):
    '''装饰器'''
    def wrapper():
        start = time.time
        res = fun()  #此处接收原函数返回值
        end = time.time
        return res   #把接收的返回值 再 return    
    return wrapper

index = time_count(index)
index()
print(res)
打印结果为:index 
          123

3.加参数

import time
def index(x,y,z,n):
        print('index',x,y,z,n)
        return 123

def time_count(fun):
    def wrapper(*args,**kwargs):  #*args和**kwargs接收所有的参数
        start = time.time
        res = fun(*args,**kwargs) #把传入index的正在参数打散
        end = time.time
        return res
    return weapper

index = time_count(index)
res = index(1,2,3,n=4)
print(res)
打印结果为:index 1 2 3 4
          123    

语法糖更简洁,省去最后装饰器赋值的操作

在被装饰函数正上方,并且是单独一行写上@装饰器名

登陆注册器 

username_list = []
def login_deco(fun):
    def wrapper(*args,**wkargs):
        if username_list:
          print('已登陆')
          res = fun(*args,**wkargs)
          return res

         username_inp = input('亲输入名字')
         pwd_inp= input('请输入密码')
         with open('user_info.txt','r',encoding='utf8') as fr:
         for user_info in fr:
             user_info= user_info.strip()
             username, userpwd = user_info.split(':')
                 if username == username_inp and userpwd == pwd_inp:
                     print('登陆成功')
                     username_list.append(username)
                        
                     res = fun(*args,**wkargs)
                     return res
                 else:
                     print('登录失败')
    return wrapper

@login_deco
def index(x,y):
    print('被装饰过的index')
    return 123

index(1,2)

三次装饰器,用来给装饰器传参数

posted on 2019-09-23 18:53  啥是py  阅读(142)  评论(0编辑  收藏  举报

导航