详解Python模块化编程与装饰器


Posted in Python onJanuary 16, 2021

我们首先以一个例子来介绍模块化编程的应用场景,有这样一个名为requirements.py的python3文件,其中两个函数的作用是分别以不同的顺序来打印一个字符串:

# requirements.py
def example1():
  a = 'hello world!'
  print (a)
  print (a[::-1])

def example2():
  b = 'hello again!'
  print (b)
  print (b[::-1])

if __name__ == '__main__':
  example1()
  example2()

其执行结果如下所示:

[dechin@dechin-manjaro decorator]$ python3 requirements.py 
hello world!
!dlrow olleh
hello again!
!niaga olleh

在两个函数中都使用到了同样的打印功能,这时候我们可以考虑,是不是可以将这两个打印语句封装为一个函数呢,这样不就可以重复利用了?这就是模块化编程思维的雏形,让我们先对样例代码进行模块化的改造:

# requirements.py
def rprint(para):
  print (para)
  print (para[::-1])

def example1():
  a = 'hello world!'
  rprint(a)

def example2():
  b = 'hello again!'
  rprint (b)

if __name__ == '__main__':
  example1()
  example2()

这里我们将两个打印语句的功能实现封装进了rprint的函数,执行结果如下:

[dechin@dechin-manjaro decorator]$ python3 requirements.py 
hello world!
!dlrow olleh
hello again!
!niaga olleh

结果当然还是与模块化之前一致的。

向下封装与向上封装

在上一章节中,我们讨论了python中的模块化编程。由于在编程过程中有可能有大量的代码需要复用,这时候就需要用一个函数来进行封装,来避免大量重复的工作。但是如果细分来看,这种封装模式只解决了一类的问题:向下封装。让我们再看一次上述改进后样例中的代码结构:

.
├── example1
│   └── rprint
└── example2
  └── rprint

我们可以发现,这里复用的rprint实际上属于两个example函数的下层,我们可以称之为向下封装了一个rprint函数。那么,如果我们转换一下需要复用的模块,变成如下的代码结构,那我们又需要用什么样的方式来实现呢?

.
├── example
│  └── rprint1
└── example
  └── rprint2

问题解读:该代码结构表示的意义为,有一个大的example函数,该函数内部嵌套不同的rprint函数可以实现不同的功能。为了方便理解,读者可以想象成是有两个函数example1和example2,这两个函数中除了rprint1和rprint2这两个函数模块不一致以外,其他的部分都是完全一样的,也就是可共用的。

Python的嵌套函数与装饰器

首先,我们为了复盘上述章节中的问题,来构造这样的一个python测试代码:

# requirements.py
def example1():
  def rprint1(para):
    print (para)
  a = 'hello world!'
  rprint1(a)

def example2():
  def rprint2(para):
    print (para[::-1])
  a = 'hello world!'
  rprint2(a)

if __name__ == '__main__':
  example1()
  example2()

以上代码的执行结果为:

[dechin@dechin-manjaro decorator]$ python3 requirements.py 
hello world!
!dlrow olleh

这个案例用到了python中嵌套函数的用法,在函数中可以嵌套实现另外的函数。这里我们注意到,虽然为了在同一个代码串中嫩够运行,两个example函数的名字取的不同,但是实际上内容是完全相同的,符合上一章节中遗留问题的代码结构。这里我们需要考虑的问题是,我们能否做到向上封装,将example的同样功能的代码实现进行归类?那么我们需要引入装饰器的用法,这里我们直接展示如何构造修饰器,以及修饰器使用的效果。

# decorator.py
def example(func):
  def wrapper(*args, **kwargs):
    a = 'hello world!'
    return func(a)
  return wrapper

@example
def rprint1(para):
  print (para)

@example
def rprint2(para):
  print (para[::-1])

if __name__ == '__main__':
  rprint1()
  rprint2()

这个代码的执行结果为:

[dechin@dechin-manjaro decorator]$ python3 decorator.py 
hello world!
!dlrow olleh

从结果上我们就可以看到,这个代码是实现了一样的效果。通过example这个装饰器,不仅封装了上层函数中所实现的功能,而且还有一个重大意义是,通过装饰器向下层函数传递了参数。这就使得,我们最终调用rprint函数的时候,不需要传入任何的参数,因为在example内已经定义了可以共享的参数。

关于Python装饰器的总结

Python的装饰器并不是一个非常难以实现的特性,其关键意义在于实现了向上封装的模块化编程。在我们过往的编程实现中,更多的是向下封装常用的、可复用的代码模块。这里通过Python所提供的装饰器特性,我们就可以将函数外部所共享的代码模块也进行封装。因此,由函数和装饰器分别实现的向下封装与向上封装的特性,共同构成了提高编码效率和编码可读性提升的模块化编程模式。

以上就是详解Python模块化编程与装饰器的详细内容,更多关于python 模块化编程与装饰器的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python实现爬虫统计学校BBS男女比例之多线程爬虫(二)
Dec 31 Python
Python实现简单的四则运算计算器
Nov 02 Python
python开发简易版在线音乐播放器
Mar 03 Python
python机器学习之神经网络(一)
Dec 20 Python
python文件操作之批量修改文件后缀名的方法
Aug 10 Python
Python中logging.NullHandler 的使用教程
Nov 29 Python
Python实现截取PDF文件中的几页代码实例
Mar 11 Python
Python3.5 Pandas模块之DataFrame用法实例分析
Apr 23 Python
django商品分类及商品数据建模实例详解
Jan 03 Python
Pycharm如何导入python文件及解决报错问题
May 10 Python
python3用PyPDF2解析pdf文件,用正则匹配数据方式
May 12 Python
Python使用random模块实现掷骰子游戏的示例代码
Apr 29 Python
删除pycharm鼠标右键快捷键打开项目的操作
Jan 16 #Python
基于pycharm 项目和项目文件命名规则的介绍
Jan 15 #Python
python制作抽奖程序代码详解
Jan 15 #Python
python中PyQuery库用法分享
Jan 15 #Python
python中pdb模块实例用法
Jan 15 #Python
python实现马丁策略的实例详解
Jan 15 #Python
pycharm 多行批量缩进和反向缩进快捷键介绍
Jan 15 #Python
You might like
php获取百度收录、百度热词及百度快照的方法
2015/04/02 PHP
分享php代码将360浏览器导出的favdb的sqlite数据库文件转换为html
2015/12/09 PHP
PHP基于GD2函数库实现验证码功能示例
2019/01/27 PHP
DOM下的节点属性和操作小结
2009/05/14 Javascript
一个js拖拽的效果类和dom-drag.js浅析
2010/07/17 Javascript
JavaScript判断文件上传类型的方法
2014/09/02 Javascript
jQuery实现带延迟的二级tab切换下拉列表效果
2015/09/01 Javascript
JS实现iframe编辑器光标位置插入内容的方法(兼容IE和Firefox)
2016/06/24 Javascript
BootStrap Table 设置height表头与内容无法对齐的问题
2016/12/28 Javascript
JS实现选定指定HTML元素对象中指定文本内容功能示例
2017/02/13 Javascript
详解webpack 配合babel 将es6转成es5 超简单实例
2017/05/02 Javascript
基于Vue.js实现tab滑块效果
2017/07/23 Javascript
React教程之封装一个Portal可复用组件的方法
2018/01/02 Javascript
vue.js或js实现中文A-Z排序的方法
2018/03/08 Javascript
Angular5中提取公共组件之radio list的实例代码
2018/07/10 Javascript
在 Angular-cli 中使用 simple-mock 实现前端开发 API Mock 接口数据模拟功能的方法
2018/11/28 Javascript
Angular PWA使用的Demo示例
2019/01/31 Javascript
layui的数据表格+springmvc实现搜索功能的例子
2019/09/28 Javascript
vue2.* element tabs tab-pane 动态加载组件操作
2020/07/19 Javascript
Python深入学习之内存管理
2014/08/31 Python
使用pandas读取csv文件的指定列方法
2018/04/21 Python
python requests 测试代理ip是否生效
2018/07/25 Python
深入理解Python中的 __new__ 和 __init__及区别介绍
2018/09/17 Python
对python中类的继承与方法重写介绍
2019/01/20 Python
Python使用reportlab模块生成PDF格式的文档
2019/03/11 Python
Python常见数据类型转换操作示例
2019/05/08 Python
浅谈Python3 numpy.ptp()最大值与最小值的差
2019/08/24 Python
python中执行smtplib失败的处理方法
2020/07/01 Python
深入理解HTML5定时器requestAnimationFrame的使用
2018/12/12 HTML / CSS
俄罗斯金苹果网上化妆品和香水商店:Goldapple
2019/12/01 全球购物
房产买卖委托公证书
2014/04/04 职场文书
高等教育学专业自荐书
2014/06/17 职场文书
暑期培训班策划方案
2014/08/26 职场文书
酒店管理失职检讨书
2014/09/16 职场文书
2014年司法所工作总结
2014/11/22 职场文书
居住证明范文
2015/06/17 职场文书