首页 > 代码库 > python基础之装饰器

python基础之装饰器

一 什么是装饰器

器即函数

装饰即修饰,意指为其他函数添加新功能

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

二 装饰器需要遵循的原则

1.不修改被装饰函数的源代码(开放封闭原则)

2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式

三 实现装饰器知识储备

装饰器=高阶函数+函数嵌套+闭包

四 高阶函数

高阶函数定义:
1.函数接收的参数是一个函数名

2.函数的返回值是一个函数名

3.满足上述条件任意一个,都可称之为高阶函数

技术分享
def foo():
    print(我的函数名作为参数传给高阶函数)
def gao_jie1(func):
    print(我就是高阶函数1,我接收的参数名是%s %func)
    func()

def gao_jie2(func):
    print(我就是高阶函数2,我的返回值是%s %func)
    return func

gao_jie1(foo)
gao_jie2(foo)

高阶函数示范
高阶函数示范
技术分享
#高阶函数应用1:把函数当做参数传给高阶函数
import time
def foo():
    print(from the foo)

def timmer(func):
    start_time=time.time()
    func()
    stop_time=time.time()
    print(函数%s 运行时间是%s %(func,stop_time-start_time))
timmer(foo)
#总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式

把函数当做参数传给高阶函数
把函数当做参数传给高阶函数
技术分享
#高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名
import time
def foo():
    print(from the foo)

def timmer(func):
    start_time=time.time()
    return func
    stop_time=time.time()
    print(函数%s 运行时间是%s %(func,stop_time-start_time))
foo=timmer(foo)
foo()
#总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能

函数返回值是函数名
函数返回值是函数名

高阶函数总结
1.函数接收的参数是一个函数名
  作用:在不修改函数源代码的前提下,为函数添加新功能,
  不足:会改变函数的调用方式
2.函数的返回值是一个函数名
  作用:不修改函数的调用方式
  不足:不能添加新功能

五 函数嵌套

def father(name):
    print(from father %s %name)
    def son():
        print(from son)
        def grandson():
            print(from grandson)
        grandson()
    son()

father(林海峰)

六 闭包

‘‘‘
闭包:在一个作用域里放入定义变量,相当于打了一个包
‘‘‘
def father(name):
    def son():
        # name=‘alex‘
        print(我爸爸是 [%s] %name)
        def grandson():
            # name=‘wupeiqi‘
            print(我爷爷是 [%s] %name)
        grandson()
    son()

father(林海峰)

七 无参装饰器

无参装饰器=高级函数+函数嵌套

基本框架

1 #这就是一个实现一个装饰器最基本的架子
2 def timer(func):
3     def wrapper():
4         func()
5     return wrapper

加上参数

1 def timer(func):
2     def wrapper(*args,**kwargs):
3         func(*args,**kwargs)
4     return wrapper

加上功能

1 import time
2 def timer(func):
3     def wrapper(*args,**kwargs):
4         start_time=time.time()
5         func(*args,**kwargs)
6         stop_time=time.time()
7         print(函数[%s],运行时间是[%s] %(func,stop_time-start_time))
8     return wrapper

 加上返回值

1 import time
2 def timer(func):
3     def wrapper(*args,**kwargs):
4         start_time=time.time()
5         res=func(*args,**kwargs)
6         stop_time=time.time()
7         print(函数[%s],运行时间是[%s] %(func,stop_time-start_time))
8         return res
9     return wrapper

使用装饰器

1 def cal(array):
2     res=0
3     for i in array:
4         res+=i
5     return res
6 
7 cal=timer(cal)
8 cal(range(10))

语法糖@

1 @timer  #@timer就等同于cal=timer(cal)
2 def cal(array):
3     res=0
4     for i in array:
5         res+=i
6     return res
7 
8 cal(range(10))

八 装饰器应用示例

技术分享
user_list=[
    {name:alex,passwd:123},
    {name:linhaifeng,passwd:123},
    {name:wupeiqi,passwd:123},
    {name:yuanhao,passwd:123},
]

current_user={username:None,login:False}

def auth_deco(func):
    def wrapper(*args,**kwargs):
        if current_user[username] and current_user[login]:
            res=func(*args,**kwargs)
            return res
        username=input(用户名: ).strip()
        passwd=input(密码: ).strip()

        for index,user_dic in enumerate(user_list):
            if username == user_dic[name] and passwd == user_dic[passwd]:
                current_user[username]=username

                current_user[login]=True
                res=func(*args,**kwargs)
                return res
                break
        else:
            print(用户名或者密码错误,重新登录)

    return wrapper

@auth_deco
def index():
    print(欢迎来到主页面)

@auth_deco
def home():
    print(这里是你家)

def shopping_car():
    print(查看购物车啊亲)

def order():
    print(查看订单啊亲)

print(user_list)
# index()
print(user_list)
home()

无参装饰器
无参装饰器
技术分享
user_list=[
    {name:alex,passwd:123},
    {name:linhaifeng,passwd:123},
    {name:wupeiqi,passwd:123},
    {name:yuanhao,passwd:123},
]

current_user={username:None,login:False}
def auth(auth_type=file):
    def auth_deco(func):
        def wrapper(*args,**kwargs):
            if auth_type == file:
                if current_user[username] and current_user[login]:
                    res=func(*args,**kwargs)
                    return res
                username=input(用户名: ).strip()
                passwd=input(密码: ).strip()

                for index,user_dic in enumerate(user_list):
                    if username == user_dic[name] and passwd == user_dic[passwd]:
                        current_user[username]=username
                        current_user[login]=True
                        res=func(*args,**kwargs)
                        return res
                        break
                else:
                    print(用户名或者密码错误,重新登录)
            elif auth_type == ldap:
                print(巴拉巴拉小魔仙)
                res=func(*args,**kwargs)
                return res
        return wrapper
    return auth_deco


#auth(auth_type=‘file‘)就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type=‘file‘)
#就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type=‘file‘参数
@auth(auth_type=ldap)
def index():
    print(欢迎来到主页面)

@auth(auth_type=ldap)
def home():
    print(这里是你家)

def shopping_car():
    print(查看购物车啊亲)

def order():
    print(查看订单啊亲)

# print(user_list)
index()
# print(user_list)
home()

带参装饰器
带参装饰器

 

参考链接:http://www.cnblogs.com/linhaifeng/articles/6140395.html

python基础之装饰器