【摘】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 ...
随机推荐
- mongodb-命令小结
小白暂时在这里记录些涉及到的 在某条记录添加一个字段: 先查询_id: db.subscriptions.find({"channel":"parking.notify. ...
- vue资料链接
vue 官方api:https://cn.vuejs.org/ vue资源精选:http://vue.awesometiny.com/ vue GitHub地址:https://github.com/ ...
- 用有限差分估计(Finite Difference Estimate)解决地理坐标与平面像素坐标转换过程的误差造成风场粒子向量失真问题
下载NCEP的气象场grib2数据,风场是二维的向量,包含u和v两个分量.这个用经纬度投影到像素坐标会产生误差,直接绘制效果不太对:( 通过插值计算得到风场粒子的预测数据wind = interp ...
- uniapp文件复制,重命名以及删除
查找某目录下的文件 plus.io.resolveLocalFileSystemURL( "_www/static/本地.png", funct ...
- SQL命令--合并查询union
union命令作用:连接两个以上的 SELECT 语句的结果组合到一个表中 一. 示例: select id, url, auth_status as authStatus, enterprise_n ...
- 初始化centos环境脚本
#! /bin/bashecho "java环境初始化开始"#功能描述: Centos8.5系统自动初始化脚本#自动配置:IP地址\Yum源\docer\docker-compos ...
- Unity UGUI --- Text组件预先获取文本的宽度和高度
转自:https://blog.csdn.net/u010180140/article/details/104049958 原作者是用lua写的.明白用什么接口就好,什么语言不重要. 给定文本内容给T ...
- wpf treeview 选中节点加载数据并绑定
<TreeView Grid.Row="0" Grid.Column="0" x:Name="FolderView" Canvas.T ...
- Echarts实现不均匀刻度的方法,自定义刻度(转)
原文地址 今天突然有个我们的咨询公司找我问一个echarts问题,这个问题确实值得一解决,很有意思. 问题是这样的.数据中有很多低于100的数值,但是最高值却能达到14000. data = [93. ...
- StatefulWidget 有状态组件 、 页面上绑定数据、改变页面数据
一.Flutter 中自定义有状态组件 在 Flutter 中自定义组件其实就是一个类,这个类需要继承 StatelessWidget/StatefulWidget. StatelessWidget ...