【摘】python和它的装饰器
python和它的装饰器
即使你没听过装饰器,你也一定知道@staticmethod
作为函数的装饰器,你可以这样写
def mydecorator(function):
def wrapped(*args, **kwargs):
# 在调用原始函数之前, 做点什么
result = function(*args, **kwargs)
# 在函数调用之后, 做点什么
# 并返回结果
return result
# 返回warpper作为装饰函数
return wrapped
作为一个例子,我写了个非常随意的
def print_hello(function):
def hello(*args, **kwargs):
print('hello start')
result = function(*args, **kwargs)
print('hello end')
return 'hello %s' % result
return hello
@print_hello
def print_world():
print('world print')
return 'world result'
if __name__ == '__main__':
print(print_world())
它的结果是
hello start
world print
hello end
hello world result
作为类的装饰器,你可以这样写
class DecoratorAsClass(object):
def __init__(self, function):
self.funciton = function
def __call__(self, *args, **kwargs):
# 在调用原始函数之前, 做点什么
result = self.funciton(*args, **kwargs)
# 在调用函数之后, 做点什么
# 并返回结果
return result
作为一个例子,我依旧写了一个很随意的
class PrintWrappedClass(object):
def __init__(self, function):
self.function = function
def __call__(self, *args, **kwargs):
print('wrapped start')
result = self.function(*args, **kwargs)
print('wrapped end')
return result
@PrintWrappedClass
class PrintWorld (object):
def print_world(self):
print('world print')
return 'world result'
def print_kitty(self):
print('kitty print')
return 'kitty result'
if __name__ == '__main__':
print(PrintWorld().print_world())
print('___')
print(PrintWorld().print_kitty())
它的结果是
wrapped start
wrapped end
world print
world result
___
wrapped start
wrapped end
kitty print
kitty result
当然,装饰器也可以传参
def repeat(number=3):
def actual_decorator(function):
def wrapper(*args, **kwargs):
result = None
for _ in range(number):
result = function(*args, **kwargs)
return result
return wrapper
return actual_decorator
@repeat(2)
def print_kitty():
print('kitty print')
return 'kitty result'
if __name__ == '__main__':
print(print_kitty())
它的结果是
kitty print
kitty print
kitty result
然后我想了想,为什么不像函数装饰器的模板那么写呢?
于是,我就随意地写了个错误的例子
def error_repeat(function, number=3):
def wrapper(*args, **kwargs):
result = None
for _ in range(number):
result = function(*args, **kwargs)
return result
return wrapper
@error_repeat
def print_world():
print('world print')
return 'world result'
它的结果是
world print
world print
world print
world result
很完美,但是当我想传参数进去的时候,犯难了
呃,就姑且将这个错误的示例当做个笑话看看吧
保存内省的装饰器
from functools import wraps
def preserving_decorator(function):
@wraps(function)
def wrapped(*args, **kwargs):
# 包装函数内部文档
return function(*args, **kwargs)
return wrapped
说实话,我没看懂这段
所以摘录下书中的原话
使用装饰器的常见错误是在使用装饰器时不保存函数元数据(主要是文档字符串和原始函数名)。
前面所有示例都存在这个问题。
装饰器组合创建了一个新函数,并返回一个新对象,但却完全没有考虑原始函数的标识。这将使得调试这样装饰过的函数更加困难,也会破坏可能用到的大多数自动生成文档的工具,因为无法访问原始的文档字符串和函数签名。
摘自 《Python高级编程》
【摘】python和它的装饰器的更多相关文章
- Python中利用函数装饰器实现备忘功能
Python中利用函数装饰器实现备忘功能 这篇文章主要介绍了Python中利用函数装饰器实现备忘功能,同时还降到了利用装饰器来检查函数的递归.确保参数传递的正确,需要的朋友可以参考下 " ...
- python函数与方法装饰器
之前用python简单写了一下斐波那契数列的递归实现(如下),发现运行速度很慢. def fib_direct(n): assert n > 0, 'invalid n' if n < 3 ...
- guxh的python笔记三:装饰器
1,函数作用域 这种情况可以顺利执行: total = 0 def run(): print(total) 这种情况会报错: total = 0 def run(): print(total) tot ...
- python设计模式之内置装饰器使用(四)
前言 python内部有许多内建装饰器,它们都有特别的功能,下面对其归纳一下. 系列文章 python设计模式之单例模式(一) python设计模式之常用创建模式总结(二) python设计模式之装饰 ...
- python 3.x 的装饰器笔记
今天学到了python的装饰器,感觉这个东西还是稍微有些复杂,所以记录下来,方便以后的查找.虽然标题是python 3.x的装饰器,但是我也没有怎么用过python 2.x,感觉上应该是和python ...
- python 中多个装饰器的执行顺序
python 中多个装饰器的执行顺序: def wrapper1(f1): print('in wrapper1') def inner1(*args,**kwargs): print('in inn ...
- Python函数编程——闭包和装饰器
Python函数编程--闭包和装饰器 一.闭包 关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数).而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数.当其中一个 ...
- python基础-内置装饰器classmethod和staticmethod
面向对象编程之classmethod和staticmethod classmethod 和 staticmethod都是python内置的装饰器 classmethod 的作用:给在类内部定义的方法装 ...
- Python 入门之 Python三大器 之 装饰器
Python 入门之 Python三大器 之 装饰器 1.开放封闭原则: (1)代码扩展进行开放 任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改.所以我们必须允许代 ...
- python中面向对象之装饰器
python面向对象内置装饰器property,staticmethod,classmethod的使用 @property 装饰器作用及使用 作用:面向对象中的方法伪装成属性 使用如下: class ...
随机推荐
- 开启Runjar , 使用beeline连接hive
要先开启hadoop服务 进入root用户hive目录 输入bin/hiveservices.sh stop 停止 输入bin/hiveservices.sh start ...
- C++ primer 5th 第一章 开始 阅读笔记
第一章 开始 第一节 编写一个简单的C++程序 不同编译器使用不同的后缀命名约定,比如cc.cpp.c. 比如main程序保存到prog1.cc中,可以使用如下命令来编译它:cc prog1.cc.其 ...
- macOS NSView改变frame后会出现黑色残留,应付的办法是不在drawRect上修改重新initWithFrame一下就行
黑色部分就是残留.是因为绘制后保留了轨迹. 解决办法是不在drawRect中做处理重新写NSView,新增方法 initWithFrame - (void)drawRect:(NSRect)dirty ...
- 对qa 工作的理解
主要职责 进行检查,包括组织级和项目级工作内容,其中组织级和项目级里包括[过程]和[资产]两项内容. 跟进不符合项,和项目经理等干系人沟通,直到不符合项问题得到解决 识别过程改进的内容,反馈给EPG. ...
- 【python基础教程】-10.开箱即用(模块的工作原理,获悉模块的功能以及常用模块)
资料来源 (1) Python基础教程第三版 1.模块的工作原理 1.1 简单的模块及使用 1.1.1 模块的本质 (1) 模块就是程序,任何python程序都可以作为模块导入; 1.1.2 简单的模 ...
- jar打包exe选型
网上一搜有篇文章写了9中不同工具方法,最后使用launch4j,其实就一点开源免费. launch4j>bsd3协议(可免费商用),像exe4j需要license. 经过摸索终于搞定一键启动并且 ...
- sqlserver ef 分页
sqlserver分页常用的有两种: 1.利用row_number set statistics time on; -- 分页查询(通用型) select top pageSize * from (s ...
- SVD动态图
library(gganimate) library(gifski) # 构造数据 phi<-pi/6 theta<-pi/3 c<-matrix(c(cos(phi),sin(ph ...
- go-浅学设计模式随记
责任链模式 组成:由多个处理器及处理器处理标志串联组成 作用:常用于处理流水线事务,利用多个处理器对同一个对象进行处理,可以利用各处理器开关 场景:常见逻辑层处理逻辑:获取参数.fetch数据.逻辑处 ...
- Dynamics 365 如何代表其他用户发送邮件
举个例子,用户A和用户B,用户B在新建电子邮件时,发件人以用户A的身份去发送邮件,这个时候需要做如下配置才可以. 首先登录用户A,在高级设置->个人设置中,配置允许其他人代表自己发送电子邮件. ...