装饰器

装饰器:

1定义:本质是函数,装饰其他函数,为其他函数添加附加功能

2原则:a.不能修改被装饰的函数源代码,有可能会导致其他问题

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

实现装饰器需要的知识点:

1知道装饰器其实就是函数

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

 只要在调用之前存在与内存中的函数,就可以调用

def test1():
    print('in the 1') #a先把这段字符串放到内存中
    test2()  #
def test2():
    print('in the 2')#b先把这段字符串放到内存中,与#a都是在调用前进行的,存起来以后再进行调用,因此不会报错
test1()


打印结果:
in the 1
in the 2    

 高阶函数:a.把一个函数名当做实参传给另外一个函数(见有点用版,在不改源代码的前提下增加功能,但是修改了调用方式)

         b.返回值包含函数名(不修改函数的调用方式)

 闲的蛋疼没卵用版

def test1():
    print('in the 1')
def test2(func):
    print(func)  #把test1赋值给func,打印test1的内存地址
    func()         #把test1赋值给了func,此行等于test1()
test2(test1)

打印结果:
<function test1 at 0x000001E373D97F28>
in the 1


 有点用版(函数名做实参传给另外一个函数):

import time
def test1():
    time.sleep(2)
    print('in the 1')
def test2(func):
    time_start=time.time()
    func() #运行test1
    time_stop=time.time()
    print('test1 start time is %s'%(time_start))
    print('test1 stop time is %s'%(time_stop))
    print('test1 running time is %s'%(time_stop-time_start))
test2(test1) #修改了调用方式

运行结果:
in the 1
test1 start time is 1517248119.7000022
test1 stop time is 1517248121.7005115
test1 running time is 2.000509262084961

 嵌套函数:

def foo():
    print('in the foo')
    def bar():      #函数中再用def定义函数才叫嵌套函数
        print('in the bar')
    bar()
foo()

打印结果:
in the foo
in the bar

局部作用域和全局作用域的访问顺序:

x=0
def grandpa():
    x=1
    def father():
        x=2
        def son():
            x=3
            print(x)
        son()
    father()
grandpa()

打印结果:
3

铺垫结束,进入正题:

装饰器

 

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "Deakin"
# Email: 469792427@qq.com
# Date: 2018/2/1
import time
def timer(func): #timer(test1)  func=test1
    def deco(*args,**kwargs): #加了args和kargs可以对有参数和无参数进行装饰
        start_time=time.time()
        func(*args,**kwargs)  #run test1()
        stop_time=time.time()
        print('func run time is %s'%(stop_time-start_time))
    return deco
@timer # 语法糖 相当于test1=timer(test1),给谁加装饰器就写在谁前面
def test1():
    time.sleep(1)
    print('in the test1')
@timer
def test2(name,age):
    print('test2:',name,age)
#test1=timer(test1) #run deco()
test1()
test2("deakin",28)

打印结果:
in the test1
func run time is 1.0002985000610352
test2: deakin 28
func run time is 0.0

 终极版:添加不同的登录方式

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "Deakin"
# Email: 469792427@qq.com
# Date: 2018/2/9
user,passwd='deakin','123456'
def auth(authtype):
    def external(func):
        def wrapper(*args,**kwargs):
            print("验证方式:%s" % authtype)
            if authtype=="local":
                username=input('key in your username:').strip()
                password=input('key in your password:').strip()
                if user==username and passwd == password:
                    print('welcome %s'%(username))
                    res=func(*args,**kwargs)
                    return res
                else:
                    exit('invalid username or password')
            elif authtype=="ldap":
                print('pls install authconfig-gui and setting on it')
                res = func(*args, **kwargs)
                return res
        return wrapper
    return external
def index():
    print('welcome to login index')
@auth(authtype='local')
def home(name):
    print('welcome to home')
    print('hello',name)
    return 'from home'
@auth(authtype='ldap')
def bbs():
    print('welcome to bbs')

index()
print(home("dj"))
bbs()

运行结果:
welcome to login index
验证方式:local
key in your username:deakin
key in your password:123456
welcome deakin
welcome to home
hello dj
from home
验证方式:ldap
pls install authconfig-gui and setting on it
welcome to bbs

 

posted @ 2018-01-30 00:15  Deakin-DJ  阅读(161)  评论(0编辑  收藏  举报