首页 > 其他 > 详细

18函数----装饰器

时间:2021-04-03 19:45:19      阅读:15      评论:0      收藏:0      [点我收藏+]

Python允许使用装饰器对函数进行装饰,装饰器可以帮助函数实现一些通用的功能,在函数调用前运行些预备代码或函数调用后执行清理工作。如:插入日志、检测性能(计时)、事务处理、缓存、权限校验等。这样编写函数时就可以专注于功能的实现,就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

定义:装饰器本质就是函数,功能是在不更改原函数的代码前提下给函数增加新的功能。包装后返回一个装饰后的函数对象,该函数对象将更新原函数对象,程序将不再能访问原始函数对象。

装饰器的基础知识:=高阶函数+函数嵌套+闭包

原则:1不修改被修饰函数的源代码     2不修改被修饰函数的调用方式,在两者的前提上扩展其功能

例子1:

# 计算时间

import time

def deco(func):
    def wrapper(*args, **kwargs):#接收任意参数
        start_time = time.time()
        res = func(*args, **kwargs)#这里有括号,运行了func函数
        end_time = time.time()
        spend_time = end_time - start_time
        print(运行时间:, spend_time)
        return res
    return wrapper

@deco  # foo=deco(foo)
def foo():
    time.sleep(1)
    print(hello cc)

foo()

 例子2:

# 验证授权
user_list = [{username:cc,password:123},{username:dd,password:111}]
def auth(func):
    def wrapper(*args, **kwargs):
        name = input(name>>>:)
        pwd = int(input(pwd>>>:))
        for i in user_list:
            if i[username] == name and i[password] == pwd:
                res = func(*args, **kwargs)
                return res
    return wrapper


@auth
def index():
    print(index....)
@auth
def shopping():
    print(shoppiing....)

index()
shopping()

 

例子3.1:带参装饰器(一)

# form functools import wraps提供了装饰器@wrap来保留原函数的属性
from functools import wraps

user_list = [{username:cc,password:123},{username:dd,password:111}]

def deco(type=a):#type=‘a‘默认参数
    def auth(func):
        @wraps(func)#保留原函数的属性
        def wrapper(*args, **kwargs):
            if type == a:
                print(这是参数aaaaaa)
            else:
                print(这是参数bbbbbb)
            name = input(name>>>:)
            pwd = int(input(pwd>>>:))
            for i in user_list:
                if i[username] == name and i[password] == pwd:
                    res = func(*args, **kwargs)
                    return res
        return wrapper
    return auth


@deco()  # @deco(type=‘a‘)=====>@auth,但是这时候带了参数type=‘a‘
def index():
    print(index....)


@deco(type=kkkk)
def shopping():
    ‘‘‘kkkkkkkkkkkkkkkkkk‘‘‘
    print(shoppiing....)

index()
shopping()
print(shopping.__doc__)#装饰器@wrap来保留原函数的属性

 例子3.2  带参装饰器(二)flask_web开发实战101页

def permission_required(permission):
    def decorator(f):
        @wraps(f)  #@wrap来保留原函数的属性
        def decorated_function(*args, **kwargs):
            if not current_user.can(permission):
                abort(403)  #服务器拒绝了你的地址请求
            return f(*args, **kwargs)
        return decorated_function
    return decorator


def admin_required(f):
    return permission_required(Permission.ADMINISTER)(f)

#下面是使用
@auth.route(/admin)
@login_required
@admin_required
def for_admin():
    return for admin


@auth.route(/moderator)
@login_required
@permission_required(Permission.MODERATE_COMMENTS)
def for_moderator():
    return for maderator

 例3.3 模拟session

# 模拟session
from functools import wraps #装饰器@wrap来保留原函数的属性

userlist = [{username:cc, pwd:123},
            {username:dd, pwd:234},
            {usernmae:ee, pwd:111}]
current_dit = {username:None, login:False} #记录用户登录状态

def auth(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        if current_dit[username] and current_dit[login]:
            return func(*args, **kwargs)
        name = input(please input your name:)
        pwd = input(please input pwd:)
        for user in userlist:
            if name==user[username] and pwd==user[pwd]:
                current_dit[username] = name
                current_dit[login] = True
                return func(*args, **kwargs)
        else:
            print(name or pwd wrong)
    return wrapper

@auth
def index():
    """dddd"""
    print(index...)

@auth
def shopping():
    print(shoping....)

index()
shopping()

  例子4:叠加多个装饰器

# 装饰器的加载顺序是从内到外的,从靠近函数的装饰器开始从内往外加载。
# 加载顺序:outer函数的调用顺序:自下而上
# 执行顺序:wrapper的执行顺序,自上而下
def outer1(func):
    print(加载了Outer1..)
    def wrapper1(*args, **kwargs):
        print(执行了wrapper1...)
        res = func(*args, **kwargs)
        return res
    return wrapper1

def outer2(func):
    print(加载了Outer2..)
    def wrapper2(*args, **kwargs):
        print(执行了wrapper2...)
        res = func(*args, **kwargs)
        return res
    return wrapper2

def outer3(func):
    print(加载了Outer3..)
    def wrapper3(*args, **kwargs):
        print(执行了wrapper3...)
        res = func(*args, **kwargs)
        return res
    return wrapper3

@outer1
@outer2
@outer3
def index():
    print(from index.....)   #====>index = outer1(outer2(outer3(index)))

print(========)
index()


#结果:
# 加载了Outer3..
# 加载了Outer2..
# 加载了Outer1..
# ========
# 执行了wrapper1...
# 执行了wrapper2...
# 执行了wrapper3...
# from index.....

 

18函数----装饰器

原文:https://www.cnblogs.com/cc-world/p/12655952.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!