失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > python中wraps_python 装饰器及标准库functools中的wraps

python中wraps_python 装饰器及标准库functools中的wraps

时间:2020-02-04 01:26:40

相关推荐

python中wraps_python 装饰器及标准库functools中的wraps

最近在看 flask的视图装饰器 时,忽然想起预(复)习一下python的装饰器.

这里有一篇比较好的讲解装饰器的书写的 Python装饰器学习(九步入门) .

这里不单独记录装饰器的书写格式了,重点是工作流程.

首先常见的装饰器 格式就是通过@语法糖,简便的写法,让流程有些不太清楚.

装饰器不带参数的情况下:

defdeco(func):

def_deco():

print("beforemyfunc()called.")

func()

print("aftermyfunc()called.")

return_deco

@deco

defmyfunc():

print("myfunc()called.")

myfunc()

运行结果:

beforemyfunc()called.

myfunc()called.

aftermyfunc()called.

myfunc()called.

这个@语法糖的作用是:

defmyfunc():

print("myfunc()called.")

myfunc=deco(myfunc)

也就是现在的myfunc不再是一开始定义的那个了,而变成了

def_deco():

print("beforemyfunc()called.")

func()

print("aftermyfunc()called.")

这一点可以通过

printmyfunc.__name__

而复杂一点的,装饰器带参数的,如:

defdeco(arg="haha"):

def_deco(func):

def__deco():

print("before%scalled[%s]."%(func.__name__,arg))

func()

print("after%scalled[%s]."%(func.__name__,arg))

return__deco

return_deco

@deco()#注意有括号

defmyfunc():

print("myfunc()called.")

@deco("haha1")

defmyfunc1():

print("myfunc()called.")

myfunc()

myfunc1()

实际的操作是,先把装饰进行了运算,即函数deco先被调用

等效于:

def_deco(func):

def__deco():

print("before%scalled[%s]."%(func.__name__,"haha"))# arg ==> "haha"

func()

print("after%scalled[%s]."%(func.__name__,"haha"))# arg ==> "haha"

return__deco

@d_deco#注意没有括号,第一处

defmyfunc():

print("myfunc()called.")

@_deco#这也没括号,第二处

defmyfunc1():

print("myfunc1()called.")

myfunc()

myfunc1()

而参数arg 使用的是默认的"haha

更直观的表达方式就是:

defdeco(arg="haha"):

def_deco(func):

def__deco():

print("before%scalled[%s]."%(func.__name__,arg))

func()

print("after%scalled[%s]."%(func.__name__,arg))

return__deco

return_deco

defmyfunc():

print("myfunc()called.")

defmyfunc1():

print("myfunc()called.")

myfunc=deco()(myfunc)

myfunc1=deco("haha1")(myfunc1)

这时再来看标准库functools中的wraps的使用,比如官网例子:

fromfunctoolsimportwraps

defmy_decorator(f):

@wraps(f)

defwrapper(*args,**kwds):

print'Callingdecoratedfunction'

returnf(*args,**kwds)

returnwrapper

@my_decorator

defexample():

"""Docstring"""

print'Calledexamplefunction'

example()

printexample.__name__

printexample.__doc__

过程就是

defmy_decorator(f):

defwrapper(*args,**kwds):

print'Callingdecoratedfunction'

returnf(*args,**kwds)

wrapper.__name__=f.__name__

wrapper.__doc__=f.__doc__

returnwrapper

example=my_decorator(example)

这样就保留了原函数名称属性和doc,

标准库中函数wraps,可以这样理解:

defwraps(f):

def_f(*args,**kwargs):

f(*args,**kwargs)

_f.__name__=f.__name

_f.__doc__=f.__doc__

return_f

上面的wraps流程可以看出,如果直接使用wraps简直就是f = f(其实不能直接使用),所以一般都是如实例这样包藏在一个装饰器函数内部.

来源:oschina

链接:/u/1755923/blog/495293

如果觉得《python中wraps_python 装饰器及标准库functools中的wraps》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。