python-装饰器


装饰器

简单的来说,装饰器就是修改其他函数功能的函数。在不改变其他函数代码的基础上,增加额外的功能。它本质上就是一个闭包函数。

装饰器的功能特点:

  1. 不修改已有函数的源代码
  2. 不修改已有函数的调用方式
  3. 给已有函数增加额外的功能

装饰器格式

基本的装饰器

def 装饰器名(func):
    def wrapper(*args,**kwargs):
    	# 要做的装饰,省略若干代码
        return func(*args,**kwargs)
    return wrapper

示例:

# 添加一个登录验证的功能
def check(fn):
    def inner():
        print("请先登录....")
        fn()
    return inner

def comment():
    print("发表评论")

# 使用装饰器来装饰函数
@check # 等价于 comment = check(comment)
comment()

带参数和返回值的装饰器

def 装饰器名(参数1,参数2): # 接收参数
    def inner(func):  # func 用来接收被装饰的函数
        def wrapper(*args, **kwargs):  # *args  **kwargs 用来接收被装饰的函数的参数
            pass  # 装饰的代码
            return func(*args, **kwargs) # 把被装饰的函数的运行结果返回
        return wrapper  # 返回包装器
    return inner

例子:

# 添加输出日志的功能
def logging(fn):
    def inner(*args, **kwargs):
        print("--正在努力计算--")
        result = fn(*args, **kwargs)
        return result
    return inner

# 使用语法糖装饰函数
@logging
def sum_num(*args, **kwargs):
    result = 0
    for value in args:
        result += value
    for value in kwargs.values():
        result += value
    return result

@logging
def subtraction(a, b):
    result = a - b
    print(result)

result = sum_num(1, 2, a=10)
print(result)

subtraction(4, 2)

多个装饰器的使用

多个装饰器的装饰过程是:离函数最近的装饰器先装饰,然后外面的装饰器再进行装饰,由内到外的装饰过程

def make_div(func):
    """对被装饰的函数的返回值 div标签"""
    def inner(*args, **kwargs):
        return "<div>" + func() + "</div>"
    return inner

def make_p(func):
    """对被装饰的函数的返回值 p标签"""
    def inner(*args, **kwargs):
        return "<p>" + func() + "</p>"
    return inner

# 装饰过程: 1 content = make_p(content) 2 content = make_div(content)
# content = make_div(make_p(content))
@make_div
@make_p
def content():
    return "人生苦短"

result = content()
print(result)

带有参数的装饰器

带有参数的装饰器就是使用装饰器装饰函数的时候可以传入指定参数,语法格式: @装饰器(参数,…)
在装饰器外面再包裹上一个函数,让最外面的函数接收参数,返回的是装饰器,因为@符号后面必须是装饰器实例。

# 添加输出日志的功能
def logging(flag):
    def decorator(fn):
    	# 这层的代码只在执行装饰器的时候执行一次
        def inner(num1, num2):
            if flag == "+":
                print("--正在努力加法计算--")
            elif flag == "-":
                print("--正在努力减法计算--")
            result = fn(num1, num2)
            return result
        return inner
    # 返回装饰器
    return decorator

# 使用装饰器装饰函数
@logging("+")
def add(a, b):
    result = a + b
    return result

@logging("-")
def sub(a, b):
    result = a - b
    return result

result = add(1, 2)
print(result)

result = sub(1, 2)
print(result)

装饰器类

装饰器还有一种特殊的用法就是类装饰器,就是通过定义一个类来装饰函数。

class 装饰器名(object):
	def __init__(self,func):
		selg.func = func
	def __call__(self,*args,**kwargs):
		pass # 写装饰代码
		return self.func(*args,**kwargs)

例子:

class Check(object):
    def __init__(self, fn):
        # 初始化操作在此完成
        self.__fn = fn

    # 实现__call__方法,表示对象是一个可调用对象,可以像调用函数一样进行调用。
    def __call__(self, *args, **kwargs):
        # 添加装饰功能
        print("请先登陆...")
        self.__fn()

@Check
def comment():
    print("发表评论")

comment()
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值