一文详解如何创建自己的Python装饰器
作者:Python 发布时间:2021-09-10 02:43:43
python装饰器在平常的python编程中用到的还是很多的,在本篇文章中我们先来介绍一下python中最常使用的@staticmethod装饰器的使用。
之后,我们会使用两种不同的方式来创建自己的自定义python装饰器以及如何在其他地方进行调用。
1、@staticmethod
@staticmethod是python开发者经常用来在一个类中声明该函数是一个静态函数时使用到的装饰器,比如创建一个HelloWorld的python类,并且在其中使用该静态装饰器声明其中的函数。
class HelloWorld():
def __init__(self):
super(HelloWorld, self).__init__()
@staticmethod
def print_hello_world():
print('welcome to hello world!')
@staticmethod装饰器一般是对于一些公共的函数,或是工具函数之类的函数进行声明,声明之后就不会将当前python类中的初始化变量信息等传入到该函数中,可以看到print_hello_world函数并没有self作为参数变量。
接下来可以在初始化@staticmethod声明的函数所在的类HelloWorld,并且调用print_hello_world函数。
hello_world = HelloWorld()
hello_world.print_hello_world()
会发现控制台直接打印出了welcome to hello world!这行字符串。
实际上在python中的函数上面加入装饰器只是为了在执行当前函数的逻辑之前去执行一些我们需要执行的业务功能,这样的操作我们通过自定义自己的装饰器也能够实现同样的效果。
2、自定义装饰器
其实,自定义装饰器的过程也比较简单,就是我们平常用到的函数或者python类的写法就能够实现。
自己实现装饰器主要有两种方式,一种是通过class类的方式来实现的,另外一种则是通过python函数嵌套的方式来实现的,下面我们先来通过第一种的方式来实现,也就是通过python类的方式来实现。
python类实现装饰器
用python类来实现装饰器时,必须明白一个知识点。python类中实际上默认有一个成员函数__call__,这个成员函数就是这个类被调用时的函数对象,若是需要自定义装饰器实际上就是在python类的__call__函数中来实现装饰器主要业务逻辑实现的。
class print_message(object):
def __init__(self, function_):
self.function_ = function_
def __call__(self):
# TODO:这里实际上是对传入的函数返回值进行的装饰,可以理解成是一种回调。
print('装饰器,{}'.format(self.function_()))
注意:在下面这行代码块中一定要注意self.function_是一个函数对象,而self.function_()是一个函数返回值得效果。
print('装饰器,{}'.format(self.function_()))
这样,我们通过python类就已经实现了python装饰器的效果,使用一个函数来试验一下效果。
@print_message
def hello_world():
return 'hello world!'
hello_world()
调用使用了@print_message装饰器的函数,它会返回我们预期的一个函数结果的打印。
# 装饰器,hello world!
python函数嵌套实现装饰器
上面的操作过程是通过重新定义了一个python类来实现装饰器的效果的,这里再使用函数嵌套的方式来实现。
因为,我们都知道在python中函数中再可以嵌套函数的,在函数中嵌套一个函数时上层的函数相对于子函数来说就是它的一个父级对象。
@print_message2
@print_message
def hello_world3():
return 'hello world!'
hello_world3()
# 装饰器,hello world!
# 装饰器2,None
使用函数嵌套的方式同样实现了函数的装饰器的效果,那么思考一下若是有两个装饰器可以在同一个函数中使用吗?
多个装饰器调用
话不多说,为了证明两个装饰器能不能放到一个函数上面使用,我们直接试一下效果如何。
@print_message2
@print_message
def hello_world3():
return 'hello world!'
hello_world3()
# 装饰器,hello world!
# 装饰器2,None
从返回结果来看,首先是两个装饰器都是执行了,从数据结果打印的顺序来看自定义的装饰器的执行顺序应该是从距离函数最近的装饰器开始执行的,也就是从下往上的顺序挨个执行该函数上面的装饰器的.
另外,装饰器2的结果为None,这是为什么呢?
因为,第一个装饰器执行的时候,它的参数应该是hello_world函数本身,但是当第二个装饰器执行的时候第一个装饰器并没有返回结果知识做了打印,这个时候第二个装饰器接收到的参数自然就是None了。
3、带参数的装饰器
说实话带参数的装饰器在python中我见到的不多,不多在java中几乎只要是装饰器都是可以加参数执行的。
还是来介绍一下,算是属于扩展知识吧,既然已经看到了这里,不妨再多掌握个小技能吧,哈哈~
我们使用pytgon嵌套的函数功能来实现这个带参数的装饰器吧,个人觉得这种方便一些。
def header(message):
def decorator(function_):
def wrapper():
return '带参数的装饰器,参数:{0},{1}'.format(message, function_())
return wrapper
return decorator
@header('Python 集中营')
def hello_world4():
return 'hello world!'
print(hello_world4())
# 带参数的装饰器,参数:Python 集中营,hello world!
OK,带参数的装饰器果然生效了,给@header加上参数@header(‘Python 集中营’),上面装饰器直接使用三层函数的嵌套来实现的。
第一层函数参数是我们需要自定义给装饰器传入的参数,第二层则是传入的已经添加了装饰器的函数本身,到了第三层才是真正的处理装饰器自己的业务逻辑的。
来源:https://blog.csdn.net/chengxuyuan_110/article/details/126682396
猜你喜欢
- 下面的demo是根据需求写的简单测试脚本#!/usr/bin/env python# coding: utf-8# 第一个列表为依赖组件和版
- 一.环境搭建1.下载安装包访问 Python官网下载地址:https://www.python.org/downloads/下载适合自己系统
- 使用pandas导入csv文件内容1. 默认导入在Python中导入.csv文件用的方法是read_csv()。使用read_csv()进行
- Python是一门弱类型语言,很多从C/C++转过来的朋友起初不是很适应。比如,在声明一个函数时,不能指定参数的类型。用C做类比,那就是所有
- 在windows 2003下,在运行web应用程序的时候出现一下错误: 服务器无法处理请求,-->对路径“C:/temp/mytest.tx
- 本文实例讲述了python中urllib模块用法。分享给大家供大家参考。具体分析如下:一、问题:近期公司项目的需求是根据客户提供的api,我
- 使用函数 ugettext() 来指定一个翻译字符串。 作为惯例,使用短别名 _ 来引入这个函数以节省键入时间.在下面这个例子中,文本 &q
- 使用Keras如果要使用大规模数据集对网络进行训练,就没办法先加载进内存再从内存直接传到显存了,除了使用Sequence类以外,还可以使用迭
- 一、项目视图分析通过上图,我们可以看到,一个完整的项目,基本包括三个部分:用户视图层、接口层、数据处理层,其中,用户视图层是用来接收用户的数
- 本文实例为大家分享了python自动发送邮件的具体代码,供大家参考,具体内容如下#coding=utf8 ''&
- 前言:交换机模式主要包括:交换机之发布订阅、交换机之关键字和交换机之通配符。1、交换机之发布订阅 发布订阅和简单的消息队列区别在于
- 1、如何统计序列中元素的出现频度实际案例:(1)某随机序列[12, 5, 6, 4, 6, 5, 5, 7, ...] 中找到出现次数最高的
- django-allauth是集成的Django应用程序,用于解决网站身份验证,用户的注册登录及账户管理,以及第三方(社交)账户的身份验证。
- 目录1 键的类型,列表/字典不可以,其它都可以2 多个对象可当作键名,顺序不同时是不同的键3 结论【有误】:今天看别人代码时发现一个事,就是
- 之前就见过很多网站在侧边栏上使用<dl />标签对来完成侧边栏栏目的布局,最近在研究DEDECMS的默认模板时,也发现该模板在大
- 本文实例总结了Python常用的小技巧。分享给大家供大家参考。具体分析如下:1. 获取本地mac地址:import uuidmac = uu
- python:simplified-chinese-menu:中文汉化(英文差的)代码高亮:Atom自带自动补全:autocomplete-
- 1 监听启动activity 信息命令adb shell logcat | grep START 可以查看apk包名和Activity名字=
- 前言在日常中有时需将 html 文件转换为 pdf、word 文件。网上免费的大多数不支持多个文件转换的情况,而且在转换几个后就开始收费了。
- 炫酷地图前期我们介绍了很多的地图模板,不管是全球的还是中国的,其实我感觉都十分的炫酷,哈哈哈,可是还有更加神奇的,更加炫酷的地图模板,下面让