码迷,mamicode.com
首页 > 编程语言 > 详细

python之路-11-装饰器

时间:2017-11-26 14:58:37      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:个数   rom   mil   welcome   基本概念   源代码   span   res   font   

11.1装饰器的基本概念

装饰器定义:本质是函数,功能是装饰其它函数(就是为其他函数添加附加功能)

原则:1.不能修改被装饰的函数的源代码

  1. 不能修改被装饰的函数的调用方式

总结:装饰器对被装饰的函数是完全透明的(被装饰的函数不知道装饰器的存在,而装饰器可装饰函数来实现所需功能)

 

实现装饰器知识储备:

 

  1. 函数即“变量”
  2. 高阶函数
  3. 把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加)
  4. 返回值中包含函数名(不修改函数的调用方式)
  5. 嵌套函数:在一个函数的函数体内用def定义一个新的函数

高阶函数+嵌套函数》装饰器

函数就是变量,定义一个函数就是把函数体赋值给函数名

 

示例1:

#!Author:lanhan
#@timmer,其实就是  test1=timmer(test1)
import time

def timmer(func):
    def warpper(*args,**kwargs):
        start_time=time.time()
        func()
        stop_time=time.time()
        print(‘the func run time is %s‘ %(stop_time-start_time))
    return warpper()

@timmer
def test1():
    time.sleep(3)
    print(‘in the test1‘)
test1

 

示例2:

#!Author:lanhan
#报错,bar()函数根本找不到函数体
def foo():
    print(‘in the foo‘)
    bar()
foo()



‘‘‘
def bar():
    print(‘in the bar‘)
def foo():
    print(‘in the foo‘)
    bar()
foo()
‘‘‘
# def foo():
#     print(‘in the foo‘)
#     bar()
# def bar():
#     print(‘in the bar‘)
# foo()



##报错,原因是内存中还没有解释到bar,foo()就执行了
def foo():
    print(‘in the foo‘)
    bar()
foo()
def bar():
    print(‘in the bar‘)
foo()

 

示例3:

#!Author:lanhan
‘‘‘
#bar函数是源代码,test1装饰bar,但缺点是修改了源代码的调用方式
import time
def bar():
    time.sleep(3)
    print(‘in the bar‘)

def test1(func):
    start_time=time.time()
    func()    #run bar  bar的运行时间
    stop_time=time.time()
    print("the func run time is %s" %(stop_time-start_time))

test1(bar)         #bar=func
#bar()      #直接调用不能增加附加功能
‘‘‘

import time
def bar():
    time.sleep(3)
    print(‘in the bar‘)
def test2(func):
    print(func)      #新增功能
    return func
#print(test2(bar))
bar=test2(bar)
bar()           #b.返回值中包含函数名(不修改函数的调用方式),bar是内存地址,相当于门牌号,bar()则是调用函数
#print(t)
#t()

 

示例4:

#!Author:lanhan
#嵌套函数
def foo():
    print(‘in the foo‘)
    def bar():     #函数即变量,所以可看成是局部变量,拥有局部变量特性。只在局部能被调用
        print(‘in the bar‘)
    bar()
foo()

 

示例5:

import time
def timer(func):       ##func=test1
    def deco():
        start_time=time.time()
        func()         ##run test1
        stop_time=time.time()
        print("the func run time is %s" %(stop_time-start_time))
    return deco      ##返回deco内存地址
@timer               ##test1=timer(test1)
def test1():
    time.sleep(3)
    print(‘in the test1‘)
@timer         ##test2=timer(test2)  = deco  test2()  =deco()
def test2():
    time.sleep(3)
    print(‘in the test2‘)
‘‘‘
test1=deco(test1)
test1()
test2=deco(test2)
test2()
‘‘‘
#test1=(timer(test1))      #test1=deco的内存地址
test1()                   #执行deco函数
#test2=(timer(test1))      #test1=deco的内存地址
test2()                   #执行deco函数

示例6:

#同个装饰器装饰不同个数的参数的函数

import time
def timer(func):       ##func=test1
    def deco(*args,**kwargs):
        start_time=time.time()
        func(*args,**kwargs)         ##run test1
        stop_time=time.time()
        print("the func run time is %s" %(stop_time-start_time))
    return deco      ##返回deco内存地址
@timer               ##test1=timer(test1)
def test1():
    time.sleep(3)
    print(‘in the test1‘)
@timer         ##test2=timer(test2)  = deco  test2()  =deco()
def test2(name,age):
    print("test2:",name,age)
#test1=(timer(test1))      #test1=deco的内存地址
test1()                   #执行deco函数
#test2=(timer(test1))      #test1=deco的内存地址
test2("lanhan",22)                   #执行deco函数

 

示例7:

#!Author:lanhan
#装饰器传参数,实现同个装饰器实现多个不同功能
import time
user,passwd = ‘lanhan‘,‘abc123‘
def auth(auth_type):
    print("auth func:",auth_type)
    def outer_wrapper(func):
        def wrapper(*args,**kwargs):
            print("wrapper func args:",*args,**kwargs)
            if auth_type == "local":
                username = input("Username:").strip()
                password = input("Password:").strip()
                if user == username and passwd == password:
                    print("\033[32;1mUser has paswd authentication\033[0m")
                    res = func(*args,**kwargs)
                    print("---after authentication")
                    return res                 ##把"from home"返回
                else:
                    exit("\033[32;1mInvalid username or password\033[0m")
            elif auth_type == "ldap":
                print("搞毛线ldap,不会...")
        return wrapper
    return outer_wrapper
def index():
    print("welcome to index page")
@auth(auth_type="local")      ## home = wrapper()
def home():
    print("welcome to home page")
    return "from home"
@auth(auth_type="ldap")
def bbs():
    print("welcome to bbs page")

index()
#home()
print(home())
bbs()

python之路-11-装饰器

标签:个数   rom   mil   welcome   基本概念   源代码   span   res   font   

原文地址:http://www.cnblogs.com/decorator/p/7898841.html

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