详解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快速从注释生成文档的方法
Dec 26 Python
python django使用haystack:全文检索的框架(实例讲解)
Sep 27 Python
批量将ppt转换为pdf的Python代码 只要27行!
Feb 26 Python
python实现pdf转换成word/txt纯文本文件
Jun 07 Python
pytorch permute维度转换方法
Dec 14 Python
Python3.6+Django2.0以上 xadmin站点的配置和使用教程图解
Jun 04 Python
Django框架组成结构、基本概念与文件功能分析
Jul 30 Python
基于django传递数据到后端的例子
Aug 16 Python
Python面向对象程序设计之继承、多态原理与用法详解
Mar 23 Python
在python中修改.properties文件的操作
Apr 08 Python
Python os库常用操作代码汇总
Nov 03 Python
详解基于Facecognition+Opencv快速搭建人脸识别及跟踪应用
Jan 21 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三元运算符的结合性介绍
2012/01/10 PHP
利用PHP生成静态html页面的原理
2016/09/30 PHP
PHP实现的多维数组去重操作示例
2018/07/21 PHP
常用简易JavaScript函数
2009/04/09 Javascript
jQuery 1.4 15个你应该知道的新特性(译)
2010/01/24 Javascript
jquery动态增加text元素以及删除文本内容实例代码
2013/07/01 Javascript
JavaScript中的数组操作介绍
2014/12/30 Javascript
jQuery实现带滚动导航效果的全屏滚动相册实例
2015/06/19 Javascript
基于jQuery实现仿51job城市选择功能实例代码
2016/03/02 Javascript
IScroll5实现下拉刷新上拉加载的功能实例
2017/08/11 Javascript
AngularJS 将再发布一个重要版本 然后进入长期支持阶段
2018/01/31 Javascript
vue如何在自定义组件中使用v-model
2018/05/14 Javascript
AngularJS ui-router刷新子页面路由的方法
2018/07/23 Javascript
element ui 表格动态列显示空白bug 修复方法
2018/09/04 Javascript
详解Vue项目在其他电脑npm run dev运行报错的解决方法
2018/10/29 Javascript
理理Vue细节(推荐)
2019/04/16 Javascript
Pyramid将models.py文件的内容分布到多个文件的方法
2013/11/27 Python
跟老齐学Python之正规地说一句话
2014/09/28 Python
Python random模块常用方法
2014/11/03 Python
Python的Flask框架中web表单的教程
2015/04/20 Python
Python字符串拼接的几种方法整理
2017/08/02 Python
Django实现从数据库中获取到的数据转换为dict
2020/03/27 Python
如何安装并在pycharm使用selenium的方法
2020/04/30 Python
pycharm 2018 激活码及破解补丁激活方式
2020/09/21 Python
python 制作python包,封装成可用模块教程
2020/07/13 Python
纯css3制作煽动翅膀的蝴蝶的示例
2018/04/23 HTML / CSS
西班牙家用电器和电子产品购物网站:Mi Electro
2019/02/25 全球购物
美国最大的在线生存商店:Survival Frog
2020/12/13 全球购物
GWT的应用有哪两种部署模式
2012/12/21 面试题
《玩具柜台前的孩子》教学反思
2014/02/13 职场文书
班级学习计划书
2014/04/27 职场文书
2015年毕业生实习评语
2015/03/25 职场文书
2015年保管员工作总结
2015/04/30 职场文书
公司表扬稿范文
2015/05/05 职场文书
苹果的回收机器人可以通过拆解iPhone获取大量的金和铜并外公布了环境保护最新进展
2022/04/21 数码科技
PYTHON InceptionV3模型的复现详解
2022/05/06 Python