Python 逼格满满的装饰器的初步认识

                   Python 逼格满满的装饰器的初步认识

基本上各种编程语言都有装饰器,而装饰器是对原有的函数和类增加更多的功能,装饰器,顾名思义,就是增强函数或类的功能的一个函数。

  • 在 Python 中“函数是一等对象” 。即函数是一种特殊类型的变量,可以和其余变量一样,可以作为参数传递给函数,也可以作为返回值返回。Python 中的整数、字符串和字典等都是一等对象。
  • 函数装饰器在导入模块时立即执行,而被装饰的函数只在明确调用时运行。

好了,需要明白以上两点,划重点========装饰器是一个函数,函数是一个对象,拿到这个对象的时候,我们可以当做一个参数传递给别的函数,也可以作为返回值返回该对象,就像处理整数,字符串,字典等等数据类型一样、   在使用装饰器时,装饰器与被装饰函数调用与否没有关系,也就是说,即使你不调用被装饰函数,装饰器依然工作。简单的说,你带了一个好看的帽子,帽子是增添你的美丽,你不带帽子依然美丽。那这个帽子不是专属你的,你也可以给他人用,谁带谁美丽,仅仅是个附属的增加美丽的工具。

装饰器的表现形式是闭包函数的形式,为什么使用闭包的形式?装饰器函数相对被装饰函数来说,是新的功能函数,闭包才可以将新的功能进行封装然后传递给被装饰函数啊。=====这里也有个重点了,装饰器必定是闭包的形式,不管它是几层的函数。下面代码简单的演示:

def outer(f):
    def inner(*args,**kwargs):
        print('这个装饰器的功能是打印数字1',1)
        f(*args,**kwargs)
    print('这是一个函数对象',inner)
    print('这也是一个函数对象',f)
    return inner#这个对象我返回了给下面调用的函数

@outer
def func(*args,**kwargs):
    print('我是被装饰函数,我执行了!!')
#func()
a=outer(func)
#执行结果:这是一个函数对象 <function outer.<locals>.inner at 0x000000000261E1F0>
#这也是一个函数对象 <function func at 0x000000000261E160>
#这是一个函数对象 <function outer.<locals>.inner at 0x000000000261E280>
#这也是一个函数对象 <function outer.<locals>.inner at 0x000000000261E1F0>
#==========================================================================
#可以发现,函数对象的内存改变了,被装饰的函数调用是被注释的情况下,
#上面的@outer执行了一遍装饰器函数,下面的a变量接收了装饰器函数又执行了一遍。
#由于是变量接收的,因此内存地址改变了。但两者功能是一致的。也就是@outer等价于 a=outer(func)
#===================================================================================
def outer(f):
    def inner(*args,**kwargs):
        print('这个装饰器的功能是打印数字1',1)
        f(*args,**kwargs)
    print('这是一个函数对象',inner)
    print('这也是一个函数对象',f)
    return inner#这个对象我返回了给下面调用的函数

@outer
def func(*args,**kwargs):
    print('我是被装饰函数,我执行了!!')
func()
#这个是正常的装饰器以及装饰器的使用,结果自己打印看看??

以上示例的装饰器十分的简单,我想,很多人都知道旗标,旗标是控制程序的运行与中断流程的一个概念,同样的,在装饰器中,我们也可以使用旗标,来控制装饰器是否启用。下面的一个示例演示的是装饰器中的旗标使用,可以通过旗标决定是否使用装饰器,从而避免了装饰器的滥用。

import time
def time_count_plus(flag=True):
    def wrap1(func):
        def wrap2(*args,**kwargs):
            if flag:
                time_flag=time.time()
                temp_result=func(*args,**kwargs)
                time.sleep(1)
                print(time.time()-time_flag-1)
            else:
                temp_result=func(*args,**kwargs)
            return temp_result
        return wrap2
    return wrap1
@time_count_plus(flag=False)
#这是带参数的装饰器
def range_loop(a,b):
    sums=1
    for i in range(a,b):
        sums+=i
    return sums

print(range_loop(0,1010000))
#被装饰器函数是一个求累加数字和的函数,装饰器的功能是计算某个程序运行的时间,其中,time.sleep(1),以#及后面的时间减法-1是为了提高该装饰器的时间计算精度,最关键的改变在装饰器内层函数内的旗标判断以及
#装饰器引用时的旗标判断,@time_count_plus(flag=False)这行如果旗标参数为False,那么装饰器将不会
#被执行,反之,任意值都会立刻执行,执行顺序见第一个示例。

以上示例与第一个示例显著不同在该装饰器是一个带参数的装饰器,当然了,既然我们可以使用flag这个旗标做参数,我们也可以使用别的任意的东西做参数,从而根据自己的需要决定哪些被装饰函数使用装饰器,以及哪一部分使用装饰器。

高级的装饰器函数我想过几天整理下思路在写吧,比如,基于类的类装饰器,装饰器的多层嵌套,静态方法装饰器等等。先这样。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晚风_END

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值