python中的装饰器

查阅官方文档、大神博客等,总结如下文档。目的是备份资料,方便以后查阅温习,也希望对大家有所帮助!

环境: python3.7

一、相关理论知识

  1. python的常识,函数和其他任何东西一样,都是对象。这意味着可以将函数当做实参传递给函数,或者在函数中将函数作为返回值。
  2. 装饰器的作用是什么呢?简单的理解就是:装饰原有的函数。什么意思呢?比如有一个函数func(a, b),它的功能是求a,b的差值,我现在有一个需求,就是想对函数功能再装饰下,求完差值后再取绝对值,但是不能在func函数内部实现,这时候就需要装饰器函数了,比如func = decorate(func)函数,将func函数作为参数传递给decorate函数,由decorate来丰富func函数,丰富完成后再返回给func,此时func的功能就丰富了。
  3. 装饰器符号“@”属于语法糖,什么意思呢?就是说,我不按照@装饰器的语法要求来写,而是按照一般python的语法要求来写完全可以。那么用@装饰器的格式来写的目的就是为了书写简单方便。2. 装饰器符号“@”属于语法糖,什么意思呢?就是说,我不按照@装饰器的语法要求来写,而是按照一般python的语法要求来写完全可以。那么用@装饰器的格式来写的目的就是为了书写简单方便

二、案例(加深对装饰器的理解)

例1: 定义并应用一个装饰器(不建议使用这种方式)

def decorate1(func):            #定义一个装饰器
	def inner(a,b):
		z=func(a,b)		
		return abs(z)
	return inner

def sub(x,y):
	return x-y

sub2=decorate1(sub)        #应用装饰器decorate1
print(sub2(1,2))           #结果是1

例2: 定义并应用一个装饰器(建议使用这种方式)

def decorate1(func):
	def inner(a,b):
		z=func(a,b)		
		return abs(z)
	return inner
#个人认为,下面的3行代码的本质是:定义了一个inner函数,其中,先调用func函数z=func(a,b),然后对返回值取绝对值并返回。
@decorate1
def sub(x,y):
	return x-y    

print(sub(1,2))  #结果是1

特别说明:

1、装饰器的定义要注意3点:参数是函数;内部再定义一个函数;返回内部定义的函数
2、’’‘当我们调用sub函数时,实际上是调用经过decorate1装饰的sub函数,返回值由表面的x-y,变成了abs(x-y).’’’

例3: 定义并应用一个装饰器,同时使用封皮wraps(建议使用这种方式)

例2中定义并使用装饰器的方式存在一个问题:经过装饰后函数的__name__、doc__等变量的值也会发生变化,会变成装饰函数中内部函数的___namedoc__等的值,但我们常常有这么一种需求,经过装饰后原函数发生变化,但__name、__doc__等属性不发生变化。为解决这个问题,引入了python装饰器之@functools.wraps。

python装饰器之@functools.wraps的作用就是,不改变原函数的结构(即__name__、__doc__等)

例3-1(未使用wraps):

def logged(func):
    def with_logging(*args, **kwargs):
        """doc of with_logging"""
        print(func.__name__ + " was called")
        return func(*args, **kwargs)
    return with_logging

@logged
def f(x):
    """doc of f"""
    return x + x * x

if __name__ == '__main__':

    print(f.__name__)  # 结果是:with_logging
    print(f.__doc__)  # 结果是:doc of with_logging

例3-2(使用wraps):

import functools

def logged(func):
    @functools.wraps(func)
    def with_logging(*args, **kwargs):
        """doc of with_logging"""
        print(func.__name__ + " was called")
        return func(*args, **kwargs)
    return with_logging

@logged
def f(x):
    """doc of f"""
    return x + x * x

if __name__ == '__main__':

    print(f.__name__)  # 结果是:f
    print(f.__doc__)  # 结果是:doc of f

@functools.wraps(func)部署在with_logging函数前,可以理解为:with_logging内部函数只是装饰func,并没有改变func的本质(即没有改变__name__、__doc__等)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
装饰器Python一种用于修改函数或类的行为的语法结构。它们允许在不修改原始代码的情况下,通过添加额外的功能来装饰函数或类。 装饰器实际上是一个函数,它接受一个函数作为输入,并返回一个新的函数作为输出。这个新的函数通常会在调用原始函数之前或之后执行一些额外的代码。 下面是一个简单的装饰器示例: ```python def decorator_function(original_function): def wrapper_function(): # 在调用原始函数之前执行额外的操作 print("Before the original function is called") # 调用原始函数 original_function() # 在调用原始函数之后执行额外的操作 print("After the original function is called") return wrapper_function @decorator_function def say_hello(): print("Hello!") # 调用经过装饰器修饰过的函数 say_hello() ``` 在上述示例,我们定义了一个名为`decorator_function`的装饰器函数。该装饰器接受一个名为`original_function`的函数作为参数,并返回一个新的函数`wrapper_function`。`wrapper_function`在调用原始函数之前和之后,分别打印了一些额外的信息。 通过在`say_hello`函数定义之前加上`@decorator_function`,我们将`say_hello`函数传递给了装饰器,并将装饰器返回的函数赋值给了`say_hello`。这样,当我们调用`say_hello`函数时,实际上是在调用经过装饰器修饰过的函数`wrapper_function`。 装饰器提供了一种灵活且可重复使用的方式来扩展函数的功能,比如添加日志记录、性能计时、输入验证等。在Python,还有一种更简洁的语法糖形式来使用装饰器,即使用`@`符号将装饰器应用到函数上,如上述示例的`@decorator_function`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值