装饰器,python装饰器

图片 1图片 2

装饰器,python装饰器

壹.哪些是装饰器

装饰器本质是函数, 其功能是, 装饰别的函数, 为任何函数增加附加作用

  1. 行使场景

若我们的先后已经上线, 那时大家想为其加多新作用,原本是要修改源代码,
不过这有一定的高危机,

此刻大家能够编写装饰器(新功能函数),为其急需增添新功能的一些修饰

三 装饰器原则

 3.一 无法改改被点缀的函数的源代码

 三.2 不可能修改棉被服装饰的函数的调用格局

 3.三 装饰器被点缀的函数来讲是晶莹的

  1. 完毕装饰器的知识储备:

   4.1 函数即“变量”

   四.贰 高阶函数 (什么是高阶函数)

        a. 把一个函数名
当作实参传递给其余一函数(在不修改棉被服装饰的源代码的景色下,增加新功能)

        b. 再次来到值中富含 函数名 (不更换函数的调用格局)

   四.三 嵌套函数 (什么是嵌套函数)

         在三个函数体内,用def阐明别的一个函数

    

# 嵌套函数
def foo():
    print("in the foo")
    def bar():
        print(" in the bar")
    bar() #bar 不能在外部调用, 因为它相当于一个局部变量
foo()


#下面是函数的调用,不是嵌套
def test1():
    test2()

test1()

5 装饰器示例

5.1 示例1

图片 3

import time
def timmer(func): #test1 作为实参传入 timmer(test1)  func=test1
    def deco():
        start_time=time.time()
        time.sleep(1)
        func() #run test1()
        stop_time=time.time()
        print("the run time is %s "%(stop_time-start_time))
    return deco
@timmer #test1=timmer(test1)
def test1():
    print("in the test1")
#可以用Python 语法糖@加在需要被装饰的函数钱
#test1=timmer(test1) #timmer(test1)结果是其函数体-->return deco-->返回deco的内存地址
print(test1) #打印test1即 deco 的内存地址
test1()

View Code

先写贰个高阶函数达成了“在不修改棉被服装饰的源代码的情况下,增加新效率”
—-
把test一 那个函数名作为实参传入timmer那些函数

为了不转移其调用情势,我们又选拔了嵌套函数,让其归来函数名 warrper

5.贰 示例二 —有参函数装饰器

图片 4

import time

def timmer(func): # func=test2
    def deco(args): #增加text2(name)参数args
        start_time = time.time()
        time.sleep(3)
        func(args) #执行args
        stop_time = time.time()
        print("the func run time is %s"%(stop_time-start_time))
    return deco #返回deco的内存地址

@timmer
def test2(name):
    print("in the test2:",name)
test2('frank') # test2() = deco(),要想让test2()加参数,则需要给deco加参数

View Code

伍.3 示例三 —装饰任意函数的装饰器

图片 5

import time

def timmer(func): 
    def deco(*args,**kwargs): #如果有增加参数,如果没有不加
        start_time = time.time()
        time.sleep(3)
        func(*args,**kwargs) #执行参数,如果有的话
        stop_time = time.time()
        print("the func run time is %s"%(stop_time-start_time))
    return deco #返回deco的内存地址

@timmer
def test2(name):
    print("in the test2:",name)
@timmer
def test1():
    print("in the test1")
test2('frank')# test2() = deco(),要想让test2()加参数,则需要给deco加参数
test1()

View Code

伍.四 示例四—终极版—装饰器也包蕴参数

图片 6

#!C:\Program Files\Python35/bin
# -*- conding: utf-8 -*-
#author: Frank
def auth(auth_type): #吸收第一层参数,装饰器的参数
    #print("auth func",auth_type)
    def out_warppage(func): #吸收第二层参数,将函数传入 func=home
        def warppage(*args,**kwargs):
            if auth_type == "local":
                user,pwd='frank','123'
                username = input("Username is :")
                password = input("Password is :")
                if username == user and password == pwd:
                    print("\033[32;1myou had login succesfull\033[0m")
                    res = func(*args,**kwargs) #run home(),index(),bbs()
                    return res
                else:
                    exit("\033[31;1m Invaild user/password\033[0m")
            else:
                print("Ldap 不会")
        return warppage
    return out_warppage


def index():
    print("welcom to index page")
@auth(auth_type="local") #当装饰器也带有参数时,我们需要在嵌套一层,
                        #装饰器的参数传给顶层函数作为实参
def home():
    print("welcom to home page")
    return "from home"
@auth(auth_type="ldap")
def bbs():
    print("weblcom to bbs")

index()
bbs()
home() #home=warapper

View Code

当语法糖也蕴藏参数时, 我们必要在嵌套壹层

a. 语法糖的参数字传送入顶层函数,加载以何种措施装饰(“local”  or “ldap”)

b.被修饰的函数当作实参被传播第三层

c. 在a.b
两步都筹算好之后,起先实践函数,那时a.b都加载进来了,便能够熟知的做判断

 

http://www.bkjia.com/Pythonjc/1202696.htmlwww.bkjia.comtruehttp://www.bkjia.com/Pythonjc/1202696.htmlTechArticle装饰器,python装饰器 一.怎么是装饰器
装饰器本质是函数, 其意义是, 装饰别的函数, 为任何函数加多附加效率 二.
接纳场景 若大家的程序…

def f():
    print("2018-06-04")

# 每次调用f的时候 在打印"2018-06-04" 之前打印一句 开始, 之后再打印一句 结束  
def wrapper(func):
    def inner():
        print("start")
        func()
        print("end")
    return inner

@wrapper
def f():
    print("2018-06-04")
from functools import wraps    #优化装饰器的模块

def wrapper(func):
    @wraps(func)                 #在这里装饰
    def inner(*args, **kwargs):  #有参数的情况
        print("start")
        ret = func(*args, **kwargs)
        print("end")
        return ret            #有返回值的情况下
    return inner

@wrapper
def f(*args, **kwargs):   #有参数的情况下
    """
    这是一个测试装饰器的函数,没什么其他的用法
    :param args:
    :param kwargs:
    :return:
    """
    print("2018-06-04")

f()  # inner()
print(f.__doc__)
print(f.__name__)

'''
start
2018-06-04
end

    这是一个测试装饰器的函数,没什么其他的用法
    :param args:
    :param kwargs:
    :return:

f
'''

但那在那之中可能有通病的,原函数假若有效率注释的话,经过装饰器装饰的函数,就看不到原函数的注明,所以大家得以优化一下

答案

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图