装饰器的主要作用是将函数增加一些功能的,它不能改变函数本身,只是在原来的函数上增加功能
举个栗子:现在我们有一个函数返回0-10的列表,但我们现在需要在这个列表里面返回0-100中所有的偶数,用装饰器可以这么实现:
def myDecorator(func):
def warpper(*args,**kwargs):
my_list = func()
return [i for i in my_list if i%2==0]
return warpper
@myDecorator
def useDecorator():
return [i for i in range(10)]
def notUseDecorator():
return [i for i in range(10)]
print(useDecorator()) # [0,2,4,6,8]
print(notUseDecorator()) # [0,1,2,3,4,5,6,7,8,9]
1、最简单的装饰器
# -*- coding:utf-8 -*-
'''示例1: 使用语法糖@来装饰函数,相当于“myfunc = deco(myfunc)”
但发现新函数只在第一次被调用,且原函数多调用了一次'''
def deco(func):
print("before myfunc() called.")
func()
print("after myfunc() called.")
return func
@deco
def myfunc():
print(" myfunc() called.")
myfunc()
# 输出结果:
before myfunc() called.
myfunc() called.
after myfunc() called.
这样的问题是装饰器只会被调用一次,即以后使用函数myfunc()输出的结果为:myfunc() called.
2、确保装饰器被调用
# -*- coding:utf-8 -*-
def deco(func):
def _deco():
print("before myfunc() called.")
func()
print(" after myfunc() called.")
# 不需要返回func,实际上应返回原函数的返回值
return _deco
@deco
def myfunc():
print(" myfunc() called.")
myfunc()
# 输出结果:
before myfunc() called.
myfunc() called.
after myfunc() called.
3、对带参数的函数进行装饰
# -*- coding:utf-8 -*-
'''示例5: 对带参数的函数进行装饰,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
def deco(func):
def _deco(a, b):
print("before myfunc() called.")
ret = func(a, b)
print("after myfunc() called. result: %s" % ret)
return ret
return _deco
@deco
def myfunc(a, b):
print(" myfunc(%s,%s) called." % (a, b))
return a + b
myfunc(1, 2)
before myfunc() called.
myfunc(1,2) called.
after myfunc() called. result: 3
3
# 输出结果:
4、让装饰器带上参数
# -*- coding:utf-8 -*-
'''示例: 在3的基础上,让装饰器带参数,
和上一示例相比在外层多了一层包装。
装饰函数名实际上应更有意义些'''
def deco(arg):
def _deco(func):
def __deco():
print("before %s called [%s]." % (func.__name__, arg))
func()
print("after %s called [%s]." % (func.__name__, arg))
return __deco
return _deco
@deco("mymodule")
def myfunc():
print(" myfunc() called.")
@deco("module2")
def myfunc2():
print("myfunc2() called.")
myfunc()
myfunc2()
# 输出结果:
before myfunc called [mymodule].
myfunc() called.
after myfunc called [mymodule].
before myfunc2 called [module2].
myfunc2() called.
after myfunc2 called [module2].
网友评论