您的位置:首页 > 编程语言 > Python开发

python装饰器:有参数的装饰器、不定长参数的装饰器、装饰有返回值的函数、通用的装饰器

2017-07-17 09:00 591 查看
将一个函数作为另一个函数的参数,返回值赋给这个函数

def func(funcname):
print("----fun 1---")
def fun_in():
print("----fun_in----1")
funcname()
print("----fun_in----2")
print("----func2-----")
return fun_in
def test():
print("----test----")

test=func(test)
test()
#上面的运行结果:
'''
----fun 1---
----func2-----
----fun_in----1
----test----
----fun_in----2
'''


上面是之前学过的函数的使用,这里我们采取装饰器的方式达到相同的效果

#前面对test的使用用到了test=func(test),可以使用装饰器来达到相同的效果
@func
def test2():
print('----test2----')

test2()
'''运行结果
----fun 1---
----func2-----
----fun_in----1
----test2----
----fun_in----2
'''

考虑多种情况的装饰器:

1 有参数的装饰器

def funcProperty(funcname):
print("----funPro 1---")
def fun_in(a,b):#test(2,0)调用的是这个函数,需要有两个参数
print("----fun_in----1")
funcname(a,b)#这里的test(2,0)作为参数传递进来,需要有两个参数
print("----fun_in----2")
print("----funcPro2-----")
return fun_in
@funcProperty
def test(a,b):
print("----the property is %d,%d----"%(a,b))

test(2,0)
'''
----funPro 1---
----funcPro2-----
----fun_in----1
----the property is 2,0----
----fun_in----2
'''

2 不定长参数

#对于不定长参数的函数的处理
def funcPro(funcName):
print("---不定长参数的传递---")
def func_in(*args,**kwargs):#前面传递的是元组,后面是字典
print("----args,kwargs---")
funcName(*args,**kwargs)
print("-----end args ,kwargs----")
print("---不定长参数传递结束--")
return func_in
@funcPro
def testThree(a,b,c):
print("----test a=%d,b=%d,c=%d----"%(a,b,c))

testThree(1,2,3) #这里参数传递几个值,都可以,跟test对应起来就可以
'''
----funPro 1---
----funcPro2-----
---不定长参数的传递---
---不定长参数传递结束--
----args,kwargs---
----test a=1,b=2,c=3----
-----end args ,kwargs----
'''

3 对带有返回值的函数进行装饰
#再次分析:上面进行装饰的时候,已经把testThree作为 参数传递过去,下面testThree(1,2,3)执行的时候,就是调用func_in
#testThree(1,2,3)指向的就是func_in,func_in中的funcName就调用了testThree(a,b,c)的内容

#使用装饰器对带有返回值的函数进行装饰
#
def funcReturn(functionName):
print("---有返回值的函数---")
def func_in():
print("--先进行装饰,将有返回值的函数作为参数传递进来")
res=functionName()
print("--调用有返回值的函数后--")
return res
print("---有返回值的函数装饰结束---")
return func_in
@funcReturn
def testRe():
print("---这个函数有返回值")
return "测试有返回结果"

ret=testRe()
print("the end value is %s"%ret)
'''
---有返回值的函数---
---有返回值的函数装饰结束---
--先进行装饰,将有返回值的函数作为参数传递进来
---这个函数有返回值
--调用有返回值的函数后--
the end value is 测试有返回结果
'''

根据前面的几种情况我们可以考虑设计一个通用的装饰器:
#一个通用的装饰器
def funcAll(funcName):
def func_in(*args,**kwargs):
ret=funcName(*args,**kwargs)
return ret
return func_in
#这个通用的装饰器,有无返回值都可以,没有返回值的话,ret=None,参数的话采用不定长参数


我们可以根据装饰器的函数的参数不同,进行不同的操作
#带有参数的装饰器
def func_arg(arg):
def funcAll(funcName):
def func_in(*args,**kwargs):
if arg=="2":#根据装饰的参数不同,可以进行不同的处理
ret=funcName(*args,**kwargs)
ret=funcName(*args,**kwargs)
else:
ret=funcName(*args,**kwargs)
print("arg is %s"%arg)
return ret
return func_in
return funcAll
#运行分析:
#1 先执行func_arg("hello")函数,这个函数return的结果是func这个函数的引用
#2 @func_arg("hello")----->@funcAll
#3 使用@func对testArg()进行装饰

@func_arg("hello")
def testArg():
print("---带有参数的装饰器---")

@func_arg("2")
def testArg2():
print("---带有参数的装饰器---")
testArg()
testArg2()
'''
---带有参数的装饰器---
arg is hello
---带有参数的装饰器---
---带有参数的装饰器---
arg is 2
'''
#带有参数的装饰器,在运行中可以根据参数进行不同运行
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: