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

09 装饰器

时间:2018-12-10 18:00:51      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:lap   顺序   名称   定义   spl   none   情况下   增加   展开   

一、闭包

定义在一个函数func1内的函数func2,在返回内部函数func2时,不是单纯返回此函数的地址,还将函数中访问到的本层和上一层(非全局)名称与值的映射一起返回了。

技术分享图片

二、装饰器

1.为啥用装饰器:现在有一个函数,在程序里多次调用,后期需要给这个函数扩展功能,根据开放封闭原则:对修改封闭,对扩展开放,即可以扩展功能,加入新的代码,但不能修改原有写好的代码。所以你需要在不改变函数调用方式何不修改函数内代码的情况下,给函数增加功能。

2.什么是装饰器:所以,装饰器即给一个已有对象添加新的增强功能的工具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。

强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式

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

 3.装饰器的使用 

技术分享图片
import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print(run time is %s %(stop_time-start_time))
        return res
    return wrapper

@timmer
def foo():
    time.sleep(3)
    print(from foo)
foo()
无参装饰器
技术分享图片
def auth(driver=file):
    def auth2(func):
        def wrapper(*args,**kwargs):
            name=input("user: ")
            pwd=input("pwd: ")

            if driver == file:
                if name == egon and pwd == 123:
                    print(login successful)
                    res=func(*args,**kwargs)
                    return res
            elif driver == ldap:
                print(ldap)
        return wrapper
    return auth2

@auth(driver=file)
def foo(name):
    print(name)

foo(egon)
有参装饰器

4.装饰器语法

被装饰函数的正上方,单独一行
        @deco1
        @deco2
        @deco3
        def foo():
            pass

        foo=deco1(deco2(deco3(foo)))

5.装饰器补充 :wraps

from functools import wraps

def deco(func):
    @wraps(func) #加在最内层函数正上方
    def wrapper(*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper

@deco
def index():
    ‘‘‘哈哈哈哈‘‘‘
    print(from index)
print(index.__doc__)

6.叠加多个装饰器

 1. 加载顺序(outter函数的调用顺序):自下而上

 2. 执行顺序(wrapper函数的执行顺序):自上而下

技术分享图片
def outter1(func1): #func1=wrapper2的内存地址
    print(加载了outter1)
    def wrapper1(*args,**kwargs):
        print(执行了wrapper1)
        res1=func1(*args,**kwargs)
        return res1
    return wrapper1

def outter2(func2): #func2=wrapper3的内存地址
    print(加载了outter2)
    def wrapper2(*args,**kwargs):
        print(执行了wrapper2)
        res2=func2(*args,**kwargs)
        return res2
    return wrapper2

def outter3(func3): # func3=最原始的那个index的内存地址
    print(加载了outter3)
    def wrapper3(*args,**kwargs):
        print(执行了wrapper3)
        res3=func3(*args,**kwargs)
        return res3
    return wrapper3

@outter1 # outter1(wrapper2的内存地址)======>index=wrapper1的内存地址
@outter2 # outter2(wrapper3的内存地址)======>wrapper2的内存地址
@outter3 # outter3(最原始的那个index的内存地址)===>wrapper3的内存地址
def index():
    print(from index)

print(===========================)
index()
示范代码

 

09 装饰器

标签:lap   顺序   名称   定义   spl   none   情况下   增加   展开   

原文地址:https://www.cnblogs.com/dongzhihaoya/p/10097026.html

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