Python基础之装饰器

一、什么是装饰器

器-工具
装饰-添加新功能
	装饰器就是定义一个函数,用该函数去为其他函数添加新功能

二、为何要用装饰器

开放封闭原则:
针对上线的功能对拓展是开放的,但是对修改源代码以及调用方式是封闭的

装饰器就是在遵循开放封闭原则的前提下为被装饰对象添加新功能
    1、不修改被装饰对象的源代码
    1、不修改被装饰对象的调用方式
概括地讲,装饰器的作用就是在不修改被装饰对象源代码和调用方式的前提下为被装饰对象添加额外的功能。装饰器经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景

三、如何用装饰器

函数装饰器分为:无参装饰器和有参装饰两种,二者的实现原理一样,都是’函数嵌套+闭包+函数对象’的组合使用的产物。

3.1无参装饰器

# 模板
def outter(func):
    def wrapper(*args,**kwargs):
        res=func(*args,**kwargs)
        return res
    return wrapper

# @outter
# ---被装饰对象代码---

# 简单计时器无参装饰器
import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        stop_time = time.time()
        print('run time is %s' % (stop_time - start_time))
        return res
    return wrapper

@timer  # index=timer(index)
def index():
    time.sleep(3)
    print('Welcome to the index page')
    return 200

index()
#Welcome to the index page
#run time is 3.004727840423584

# 叠加多个无参装饰器
@deco3
@deco2
@deco1
def index():
    pass

# 语义如下
index=deco3(deco2(deco1(index)))

3.2有参装饰器

# 有参装饰器模板
def outter2(x):
    def outter(func):
        def wrapper(*args, **kwargs):
            res = func(*args, **kwargs)
            return res
        return wrapper
    return outter

# @outter2(111)
# ---被装饰对象代码---

# 举例:为被装饰对象添加认证功能的装饰器
import time

def login(x, engine='file'):
    def auth(func):
        def wrapper(*args, **kwargs):
            print("=====>", x)
            inp_user = input("username>>>: ").strip()
            inp_pwd = input("password>>>: ").strip()
            if engine == "file":
                print("基于file的认证")
                if inp_user == "arthur" and inp_pwd == "123":
                    print('login successful')
                    res = func(*args, **kwargs)
                    return res
                else:
                    print('username or password error')
            elif engine == "mysql":
                print("基于mysql的认证")
            elif engine == "ldap":
                print('基于ldap的认证')
            else:
                print("认证来源未知")
        return wrapper
    return auth

@login(11, engine='file') # @auth index=auth(index) index=wrapper
def index():
    time.sleep(1)
    print('from index')

@login(22, engine='mysql') # @auth home=auth(home) home=wrapper
def home(name):
    time.sleep(2)
    print('home page,welcome %s' % name)
    return 123

index()
home("arthur")

# functools模块下提供一个装饰器wraps,可以保留原函数的文档和函数名属性
import time
from functools import wraps

def timmer(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        stop = time.time()
        print('run time is:%s' % (stop - start))
        return res
    # wrapper.__name__=func.__name__
    # wrapper.__doc__=func.__doc__
    return wrapper


@timmer  # index= timmer(index)  # index=wrapper
def index():
    """index函数"""
    time.sleep(1)
    print('from index')

print(index)
print(index.__name__)
help(index)
# 输出结果:
<function index at 0x7fafc61079d0>
index
Help on function index in module __main__:

index()
	index函数
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值