我是靠谱客的博主 超级发卡,最近开发中收集的这篇文章主要介绍python中wraps_python 装饰器及标准库functools中的wraps,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

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

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

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

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

def deco(func):

def _deco():

print("before myfunc() called.")

func()

print("  after myfunc() called.")

return _deco

@deco

def myfunc():

print(" myfunc() called.")

myfunc()

运行结果:

before myfunc() called.

myfunc() called.

after myfunc() called.

myfunc() called.

这个@语法糖的作用是:

def myfunc():

print(" myfunc() called.")

myfunc = deco(myfunc)

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

def _deco():

print("before myfunc() called.")

func()

print("  after myfunc() called.")

这一点可以通过

print myfunc.__name__

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

def deco(arg="haha"):

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()#注意有括号

def myfunc():

print(" myfunc() called.")

@deco("haha1")

def myfunc1():

print(" myfunc() called.")

myfunc()

myfunc1()

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

等效于:

def _deco(func):

def __deco():

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

func()

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

return __deco

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

def myfunc():

print(" myfunc() called.")

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

def myfunc1():

print(" myfunc1() called.")

myfunc()

myfunc1()

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

更直观的表达方式就是:

def deco(arg="haha"):

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

def myfunc():

print(" myfunc() called.")

def myfunc1():

print(" myfunc() called.")

myfunc = deco()(myfunc)

myfunc1 = deco("haha1")(myfunc1)

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

from functools import wraps

def my_decorator(f):

@wraps(f)

def wrapper(*args, **kwds):

print 'Calling decorated function'

return f(*args, **kwds)

return wrapper

@my_decorator

def example():

"""Docstring"""

print 'Called example function'

example()

print example.__name__

print example.__doc__

过程就是

def my_decorator(f):

def wrapper(*args, **kwds):

print 'Calling decorated function'

return f(*args, **kwds)

wrapper.__name__ = f.__name__

wrapper.__doc__  = f.__doc__

return wrapper

example = my_decorator(example)

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

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

def wraps(f):

def _f(*args,**kwargs):

f(*args,**kwargs)

_f.__name__ = f.__name

_f.__doc__  = f.__doc__

return _f

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

来源:oschina

链接:https://my.oschina.net/u/1755923/blog/495293

最后

以上就是超级发卡为你收集整理的python中wraps_python 装饰器及标准库functools中的wraps的全部内容,希望文章能够帮你解决python中wraps_python 装饰器及标准库functools中的wraps所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部