Python 装饰器@,对函数进行功能扩展操作示例【开闭原则】


Posted in Python onOctober 17, 2019

本文实例讲述了Python 装饰器@,对函数进行功能扩展操作。分享给大家供大家参考,具体如下:

装饰器可以对原函数进行功能扩展,但还不需要修改原函数的内容(开闭原则),也不需要修改原函数的调用。

demo.py(装饰器,@):

# 闭包
def w1(func):
  def inner():
    # 对原函数进行功能扩展
    print("功能扩展")
    func()
    # return func() # 如果原函数需要返回值,可以return
  return inner # 闭包
@w1
# 相当于 f1 = w1(f1)
def f1():
  print('f1') # 原函数不需要修改
f1() # 原函数的调用也不需要修改

demo.py(装饰器通用格式,对不定长参数并且有返回值的函数进行装饰):

def set_func(func):
  def call_func(*args, **kwargs):
    print("装饰器扩展的功能")
    return func(*args, **kwargs) # 这里的*和*表示拆包。 不管有没有返回值,return都没问题。
  return call_func
@set_func # 相当于 test1 = set_func(test1)
# 对含有不定长参数并且有返回值的函数进行装饰。
def test1(num, *args, **kwargs):
  print("-----test1----%d" % num)
  return "ok"
ret = test1(100)
print(ret)

demo.py(多个装饰器的装饰顺序):

def add_1(func):
  def call_func(*args, **kwargs):
    print("装饰器1 扩展的功能")
    return func(*args, **kwargs)
  return call_func
def add_2(func):
  def call_func(*args, **kwargs):
    print("装饰器2 扩展的功能")
    return func(*args, **kwargs)
  return call_func
@add_2
@add_1
# 先装饰add_1,再装饰add_2
def test1():
  print("------test1------")
test1() # 在调用函数之前就已经装饰好了。
# 装饰器2 扩展的功能
# 装饰器1 扩展的功能
# ------test1------

demo.py(用类充当装饰器):

# 用类充当装饰器
class Test(object):
  def __init__(self, func):
    self.func = func
  def __call__(self, *args, **kwargs):
    print("这里是装饰器添加的功能.....")
    return self.func(*args, **kwargs)
@Test # 相当于get_str = Test(get_str) # 实例化对象,调用__init__方法。
def get_str():
  return "haha"
print(get_str())  # 实例对象(),会自动调用对象的__call__方法。

@functools.wraps修饰装饰器的内层函数。(修饰内层函数后,被装饰器装饰的函数的__name__、__doc__不会被装饰器改变)

demo.py(@functools.wraps修饰装饰器的内层函数):

# coding:utf-8
import functools # 导入
# 自定义的装饰器
def login_required(func):
  @functools.wraps(func)
  # 装饰器的内层函数,一般要加@functools.wraps装饰器
  def wrapper(*arg, **kwargs):
    """wrapper的说明文档"""
    # 。。。
    return func(*arg, **kwargs)
  return wrapper
# 使用自定义的装饰器
@login_required
def demofunc():
  """demofunc的说明文档"""
  pass
print(demofunc.__name__)  # 不加@functools.wraps装饰器时:"wrapper"。 加装饰器时:"demofunc"
print(demofunc.__doc__)  # 不加@functools.wraps装饰器时:"wrapper的说明文档"。 加装饰器时:"demofunc的说明文档"

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
初步解析Python下的多进程编程
Apr 28 Python
python实现发送和获取手机短信验证码
Jan 15 Python
python merge、concat合并数据集的实例讲解
Apr 12 Python
python 在屏幕上逐字显示一行字的实例
Dec 24 Python
神经网络相关之基础概念的讲解
Dec 29 Python
浅谈Python的条件判断语句if/else语句
Mar 21 Python
python3实现单目标粒子群算法
Nov 14 Python
python判断两个序列的成员是否一样的实例代码
Mar 01 Python
如何搭建pytorch环境的方法步骤
May 06 Python
python3+opencv 使用灰度直方图来判断图片的亮暗操作
Jun 02 Python
浅谈tensorflow 中的图片读取和裁剪方式
Jun 30 Python
Python猫眼电影最近上映的电影票房信息
Sep 18 Python
python实现复制文件到指定目录
Oct 16 #Python
如何解决django-celery启动后迅速关闭
Oct 16 #Python
Python发送邮件的实例代码讲解
Oct 16 #Python
python运用sklearn实现KNN分类算法
Oct 16 #Python
python sklearn常用分类算法模型的调用
Oct 16 #Python
Python使用selenium + headless chrome获取网页内容的方法示例
Oct 16 #Python
使用python实现kNN分类算法
Oct 16 #Python
You might like
PHP中对数据库操作的封装
2006/10/09 PHP
php 模拟POST|GET操作实现代码
2010/07/20 PHP
DOM XPATH获取img src值的query
2013/09/23 PHP
laravel 时间格式转时间戳的例子
2019/10/11 PHP
Laravel开启跨域请求的方法
2019/10/13 PHP
js 父窗口控制子窗口的行为-打开,关闭,重定位,回复
2010/04/20 Javascript
JavaScript 基础篇之对象、数组使用介绍(三)
2012/04/07 Javascript
js实现两个值相加alert出来精确到指定位
2013/09/25 Javascript
JavaScript解析json格式数据简单示例
2014/12/09 Javascript
一道JS前端闭包面试题解析
2015/12/25 Javascript
jQuery toggle 代替方法
2016/03/22 Javascript
详解jQuery中的deferred对象的使用(一)
2016/05/27 Javascript
D3.js实现折线图的方法详解
2016/09/21 Javascript
原生JS写Ajax的请求函数功能
2017/12/22 Javascript
babel之配置文件.babelrc入门详解
2018/02/22 Javascript
express默认日志组件morgan的方法
2018/04/05 Javascript
浅谈监听单选框radio改变事件(和layui中单选按钮改变事件)
2019/09/10 Javascript
vue封装swiper代码实例解析
2019/10/08 Javascript
Node使用Selenium进行前端自动化操作的代码实现
2019/10/10 Javascript
layui实现数据表格自定义数据项
2019/10/26 Javascript
vue通过v-html指令渲染的富文本无法修改样式的解决方案
2020/05/20 Javascript
JQuery获得内容和属性方法解析
2020/05/30 jQuery
浅谈vue项目利用Hbuilder打包成APP流程,以及遇到的坑
2020/09/12 Javascript
[03:02]生活中的Dendi之野外度假篇
2016/08/09 DOTA
python 转换 Javascript %u 字符串为python unicode的代码
2016/09/06 Python
python 爬虫出现403禁止访问错误详解
2017/03/11 Python
Python面向对象特殊成员
2017/04/24 Python
python中yield的用法详解——最简单,最清晰的解释
2019/04/04 Python
使用virtualenv创建Python环境及PyQT5环境配置的方法
2019/09/10 Python
Python 实现毫秒级淘宝抢购脚本的示例代码
2019/09/16 Python
python3.8 微信发送服务器监控报警消息代码实现
2019/11/05 Python
Spring Boot中使用IntelliJ IDEA插件EasyCode一键生成代码详细方法
2020/03/20 Python
python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)
2020/04/08 Python
Flask-SocketIO服务端安装及使用代码示例
2020/11/26 Python
Omio中国:全欧洲低价大巴、火车和航班搜索和比价
2018/08/09 全球购物
2019大学竞选班长发言稿
2019/06/27 职场文书