码迷,mamicode.com
首页 > 其他好文 > 详细

闭包函数 装饰器

时间:2019-04-02 17:06:14      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:wrapper   主页   user   nbsp   strip   rgs   input   false   内存地址   

什么是闭包函数

  闭:指的是闭包函数数定义在一个函数内部的函数

  包:该内部函数包含对外城函数作用域名字的引用

  需要结合函数对象的概念将闭包函数返回到全局作用域去使用,从而打破函数层级的限制

为什么要用闭包函数

  闭包函数提供了一种为函数体传值的解决方案

如何用闭包函数

# 为函数体传值的方式一:参数
# def func(x,y):
#     print(x+y)
#
# func(1,2)          3

# 为函数体传值的方式二:闭包
def outter(x,y):
    # x=1
    # y=2
    def func():
        print(x+y)
    return func

f=outter(1,2) 
f()                          3
f()                          3
f()                          3

 解决方案一:参数
# def get(url):
#     response=requests.get(url)
#     if response.status_code == 200:
#         print(len(response.text))

# get(‘https://www.baidu.com‘)
# get(‘https://www.baidu.com‘)
# get(‘https://www.baidu.com‘)
# get(‘https://www.tmall.com‘)
# get(‘https://www.tmall.com‘)

# url1=‘https://www.baidu.com‘
# url2=‘https://www.tmall.com‘
#
# get(url1)
# get(url1)
# get(url1)
#
# get(url2)
# get(url2)
# get(url2)

 解决方案二:闭包
# def outter(url):
#     # url=‘https://www.baidu.com‘
#     def get():
#         response=requests.get(url)
#         if response.status_code == 200:
#             print(len(response.text))
#     return get
#
# baidu=outter(‘https://www.baidu.com‘)
# baidu()
# baidu()
# baidu()
#
# tmall=outter(‘https://www.tmall.com‘)
# tmall()
# tmall()
# tmall()

装饰器   

  器:指的是具备某一功能的工具

  装饰:值的是为了被装饰器对象添加新的功能

  装饰器就是用来为了被装饰对象添加新功能的工具

   注意: 装饰器本身可以是任意可调用对象,被装饰器的对象也可以是任意可调用对象

为什么用装饰器

  开放封闭原则:封闭值的是对修改源代码封闭,对扩展功能开放

  装饰器的实现必须遵循量大原则:

    1 不修改被装饰对象的源代码

    2不修改被装饰对象的调用方式

  装饰器的目标:就是在遵循1和2原则的前提下为被装饰对象添加上新功能

import time

def index():
    print(welcome to index page)
    time.sleep(3)

def outter(func): # func=最原始那个index的内存地址
    def wrapper():
        start=time.time()
        func() #最原始的那个index的内存地址()
        stop=time.time()
        print(run time is %s %(stop - start))
    return wrapper

index=outter(index) #index=outter(最原始那个index的内存地址) #index=wrapper的内存地址
index() #wrapper的内存地址()

装饰器的语法糖:在被装饰器对象正上方单独一行写@装饰器的名字

  python解释器一旦运行到@装饰器的名字,就会调用装饰器然后将被装饰函数的内存地址当做参数传递给装饰器,最终将装饰器调用的结果赋值给原函数名 (原函数名=@外层函数运行结果返回值(二层函数名:就是加新功能的新函数名))

import time
#
# def timmer(func): #func=最原始那个home函数的内地址
#     def wrapper(*args,**kwargs): #args=(‘egon‘,) kwargs={}
#         start=time.time()
#         res=func(*args,**kwargs) #最原始那个home函数的内地址(‘egon‘)
#         stop=time.time()
#         print(‘run time is %s‘ %(stop - start))
#         return res
#     return wrapper
#
# @timmer #index=timmer(index)
# def index():
#     print(‘welcome to index page‘)
#     time.sleep(3)

装饰器模板

import time

def outer(func):
  def wrapper(*args,**kwargs):
    #在调用函数前增加新功能
    res=func(*args,**kwargs) #调用被装饰的 也就是最原始的那个函数
    #在调用函数后加功能
    return res
  return wrapper

@outter #index=outer(index) #index =wrapper
def index():
  print (‘welcome to index page‘)
  time.sleep(3)

index()


ef wrap(fn):
def inner(*args,**kwargs): print(前面增功能) result=fn(*args,**kwargs) print(后面增功能) return result return inner @wrap def fn1(): print(fn1的原功能) @wrap def fn2(a,b): print(fn2的原有功能) @wrap def fn3(): print(fn3的原有功能) return True @wrap def fn4(a,*,x): print(fn4原有功能) return True fn1() fn2(10,29) fn1() fn4(19,x=7)
认证功能的装饰器
import time

def auth(func):
    def wrapper(*args,**kwargs):
        inp_user = input(please input your username: ).strip()
        inp_pwd = input(please input your password: ).strip()
        if inp_user == egon and inp_pwd == 123:
            print(login successfull)
            res=func(*args,**kwargs) # 调用最原始的那个/也就是被装饰的那个函数
            return res
        else:
            print(username or password error)
    return wrapper

@auth # index=auth(index) #index=wrapper
def index():
    print(welcome to index page)
    time.sleep(3)

index() #wrapper()



is_login = False  # 登录状态

def login():
usr = input(‘usr: ‘)
if not (len(usr) >= 3 and usr.isalpha()):
print(‘账号验证失败‘)
return False
pwd = input(‘pwd: ‘)
if usr == ‘abc‘ and pwd ==‘123qwe‘:
print(‘登录成功‘)
is_login = True
else:
print(‘登录失败‘)
is_login = False


# 完成一个登录状态校验的装饰器
def check_login(fn):
def inner(*args, **kwargs):
# 查看个人主页或销售功能前:如果没有登录先登录,反之可以进入其功能
if is_login != True:
print(‘你未登录‘)
login()
# 查看个人主页或销售
result = fn(*args, **kwargs)
return result
return inner

# 查看个人主页功能
@check_login
def home():
print(‘个人主页‘)

# 销售功能
@check_login
def sell():
print(‘可以销售‘)

home()

 

闭包函数 装饰器

标签:wrapper   主页   user   nbsp   strip   rgs   input   false   内存地址   

原文地址:https://www.cnblogs.com/lakei/p/10643388.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!