装饰器python符号_python 中的装饰器详解

装饰器

闭包

闭包简单的来说就是一个函数,在该函数内部再定义一个函数,并且这个内部函数用到了外部变量(即是外部函数的参数),最终这个函数返回内部函数的引用,这就是闭包。

def decorator(par): #定义一个外部函数

def wrapper(kkk): #定义一个内部函数

test = par + kkk #内部函数使用了外部函数的参数

print(test)

return wrapper #返回了内部函数的引用

if __name__ == "__main__":

tt = decorator('mmm')

tt('nnn')

# 输出结果

# mmmnnn

装饰器

python 中的装饰器用@符号来表名,常见的代码是在函数名字上面@classmethod,@+函数名是python中的一种语法糖,因为解释器会对这种语法做特殊处理。

@decorator #等价于 func = decorator(func)

def func():

pass

下面通过代码简单说一下装饰器

def decorator(func):

def wrapper():

print("装饰前------decorator---")

func()

print("装饰后------decorator---")

return wrapper

def decorator1(func):

def wrapper1():

print("装饰前-----decorator1***********")

func()

print("装饰后-----decorator1*********")

return wrapper1

@decorator #等价于 test = decorator(test)

def test():

print('test-------')

def test1():

print('test1*******')

#等价于 test3 = decorator1(test3),括号里test3等于下面等号左边的test3

@decorator1

@decorator #等价于 test3 = decorator(test3)

def test3():

print('test3&&&&&&&')

if __name__ == "__main__":

test()

test1 = decorator(test1)

test1()

test3()

输出结果如下:

装饰前------decorator---

test-------

装饰后------decorator---

装饰前------decorator---

test1*******

装饰后------decorator---

装饰前-----decorator1***********

装饰前------decorator---

test3&&&&&&&

装饰后------decorator---

装饰后-----decorator1*********

上面代码简单说明了装饰器的作用和实现原理,当有多个装饰器同时对一个函数进行装饰时,先装饰内层然后装饰外层

函数实现装饰器

函数的装饰器分为两种情况:被装饰的函数带有参数和返回值,装饰器带有参数,下面通过代码对这两种情况进行说明:

被装饰函数带有参数和返回值

def pre_decorator(par='pre_dec')

def decorator(fun):

def dec_fun(*args, **kwargs): #可变参数

print("装饰器的参数---%s" % pre)

print("装饰前-----------")

ret = fun(*args, **kwargs) #函数执行的地方

print("装饰后-----------")

return ret #被装饰函数没有返回值的时候为None

return dec_fun

return decorator

@decorator

def sum(a,b,c):

print('执行函数')

return a+b+c

if __name__ == "__main__":

test = sum(2,3,6)

print(test)

输出结果:

装饰前-----------

执行函数

装饰后-----------

11

函数装饰器带有参数

在阅读一些开源框架的代码的时候,经常会遇到装饰器带有参数,带有参数的装饰器能够进一步丰富装饰器的功能,当装饰器含有参数时,我们要想获取并利用装饰器的参数,需要在原来装饰器基础上再封装一层闭包,请看下面代码

def pre_decorator(par='pre_dec'): # 装饰器添加一个默认字符串

def decorator(fun):

def dec_fun(*args, **kwargs): # 可变参数

print("装饰器的参数---%s" % par)

print("装饰前-----------")

ret = fun(*args, **kwargs) # 函数执行的地方

print("装饰后-----------")

return ret # 被装饰函数没有返回值的时候为None

return dec_fun

return decorator

@pre_decorator('haha')

def sum(a,b,c):

print('执行函数')

return a+b+c

if __name__ == "__main__":

test = sum(2,3,6)

输出结果:

装饰器的参数---haha

装饰前-----------

执行函数

装饰后-----------

类实现装饰器

类装饰器不带有参数 和 带有参数,其实现方式有点区别

当类装饰器不带有参数

class Decorator(object):

def __init__(self, func):

self.func = func

def __call__(self, *args, **kwargs):

print('装饰前----------')

ret = self.func(*args, **kwargs)

print('装饰后----------')

return ret

# 当装饰器没有参数时,其本质还是等价于 sum = Decorator(sum),被装饰函数sum引用传到__init__()中

# 相当于实例化一个对象,对象后面加括号比如sum(), 要调用类中的__call__()

@Decorator # 相当于sum = Decorator(sum)

def sum(a, b, c):

print('执行函数--------')

return a+b+c

if __name__ == "__main__":

print(sum(1,2,3))

运行结果:

装饰前----------

执行函数--------

装饰后----------

6

类装饰器含有参数时

class Decorator(object):

def __init__(self, par=''):

self.par = par

print('类装饰器的参数是 %s' % self.par)

# 被装饰函数的引用传到__call__中,需要通过闭包来装饰

def __call__(self, func):

def dec_fun(*args, **kwargs):

print('装饰前----------')

ret = func(*args, **kwargs)

print('装饰后----------')

return ret

return dec_fun

# 当类装饰器含有参数时,其本质等价于 sum = Decorator(par='parameter')(sum)

# 那么此时装饰器的参数par='parameter'传到了__init__()中,而被装饰函数sum的引

# 用传到了__call__()中了

@Decorator(par='parameter') # 相当于 sum = Decorator(par='parameter')(sum)

def sum(a, b, c):

print('执行函数--------')

return a+b+c

if __name__ == "__main__":

print(sum(1,2,3))

输出结果:

类装饰器的参数是 parameter

装饰前----------

执行函数--------

装饰后----------

6

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值