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装饰器函数wraps
python的装饰器是python的重要特性之一,通过装饰器你能够在执行已有的操作的同时,去执行额外的操作.装饰器的主要作用在不改变原有函数或者类等内部的实现的前提下,对其进行功能的拓展.这是装饰器最 ...
- python中的装饰器有哪些-python 装饰器以及开发中常用的例子
有时候我们想为多个函数,同意添加某一种功能,比如及时统计,记录日志,缓存运算结果等等,而又不想改变函数代码 那就定义装饰器函数,用它来生成一个在原函数基础添加了新功能的函数,代替原函数 参考金角大王的 ...
- python装饰器原理-python 中的装饰器及其原理
装饰器模式 此前的文章中我们介绍过装饰器模式: 装饰器模式中具体的 Decorator 实现类通过将对组建的请求转发给被装饰的对象,并在转发前后执行一些额外的动作来修改原有的部分行为,实现增强 Com ...
- 为什么在Python代码中需要装饰器
Python is praised for its clarity and syntactic sugariness. In this article, I will teach you to use ...
- python类装饰器详解-Python类中的装饰器在当前类中的声明与调用详解
我的Python环境:3.7 在Python类里声明一个装饰器,并在这个类里调用这个装饰器. 代码如下: class Test(): xx = False def __init__(self): pa ...
- python 类装饰器和函数装饰器区别_python进阶之装饰器之4在类中定义装饰器,将装饰器定义为类,两者的区别与联系...
# 把装饰器定义为类 # 定义中需要实现__call__(),__get__() 方法 import types from functools import wraps class Profiled: ...
- python中装饰器的使用教程详解(wraps)
先看下面的函数简单理解一下 示例代码: import loggingdef use_logging(func):logging.error("%s is running" % fu ...
- 为什么说想到Python中的装饰器是天才
为什么说想到Python中的装饰器是天才 只需一个@符号就能分析.测试和重复使用你的代码 带着魔杖的仙女在Python代码中飞舞 软件中有没有什么是神奇的小魔法? 有,装饰器却非常接近! 如果说有一件 ...
- Python中的装饰器是什么?装饰器是如何工作的?
Python很早就引入了装饰器--在PEP-318中,作为一种简化函数和方法定义方式的机制,这些函数和方法在初始定义之后必须进行修改. 这样做的最初动机之一是,使用classmethod和static ...
最新文章
- 看完这篇缓存双写分析,你面试不再有问题呢~
- .net 插件式开发学习总结
- The python debugger调试(PDB)的简介
- 浅谈android hook技术
- redis安装,主从集群
- Web Storage中的sessionStorage和localStorage
- React开发(167):...数组拼接
- 泄漏 iOS 关键源码的人,居然是苹果的一个实习生
- php 类似百度分页,写了一个仿百度贴吧分页效果的分页类,有人要么?
- Keil(MDK) 5 软件安装教程
- 数据结构_树状数组 详解
- IE 浏览器阻止打印页面的方法
- 自学单片机是否先学c语言,学习单片机需要先学好C语言再去学单片机吗
- 【机器学习】【决策树】自己动手用Python实现一个类:in样本集,out特征分布、概率密度、熵、条件熵、信息增益、信息增益比
- cnpm和npm使用,遇到的问题及解决方法
- 帆软报表决策系统忘记密码了,使用重置密码插件
- 绕口令:《舌头是怎样练成的》
- 万年历C语言程序可参考的文献,万年历的c语言程序
- 超级服装分床省料软件
- win10打开.md文件
热门文章
- springboot快速开发框架推荐,接私活利器
- C#中saveFileDialog的使用
- mysql escape的用法_#ORACLE 每日一点# ESCAPE用法
- SIFT原理及步骤详解
- centos7安装redis单机版(阿里云)
- 基于MATLAB的药物扩散仿真系统设计与实现 文档+上机实验报告+项目源码+运行说明
- getline的使用
- 宽带和流量是分开的吗_流量和宽带有什么区别-流量和宽带有什么区别?哪个划算?-综投网...
- 设计模式--第七章 克隆模式
- Spring Boot 启动事件和监听器,太强大了!