最近接受老代码,mmp的,说是重新运行运行起来,那还不如重写呢,因为有很多毛病,不能直接运行,pep8就不用妄想奢望了,还有包括语法错误问题和内存严重泄露的问题(运行几分钟后python.exe进程达到2GB直至把电脑卡死),而且很难看懂代码,修改也不方便。

1、笼统的说,大部分人都认为面向对象适合大项目,小项目使用面向过程好,那么这到底是为什么呢,不知道大家有没有思考和体会和实践对比过,还是对此完全没有任何心得体会只是跟风这麽认为?

2、python是很精简的,300行抵得上java500行。

当一个300行的面向过程的,写了十几个函数,一环套一环的return和传参,看得就会脑袋发烫了,除了自己能看懂别人是看不懂的,因为python很多人都没写参数的意义注释和类型注释(这两者缺一不可,java只需要有参数含义注释就行了,因为参数前缀已经是强制声明类型了,不需要再写类型注释),所以这种代码函数到底是干什么的,还需要跳转到调用它的地方去,频繁的跳转效率很低,尤其是完成长流程的项目,一环套一环的return和传参更是如此。

3、在单文件或者顶层运行文件时候,写一个完成一个完整任务流程的面向过程的300行的代码,应该使用下面这种思维方式,才能保证可读性好:

少return少传参,多写全局变量,因为 很多函数都操作相同的东西,操作这个东西后传递给下一个函数,再传给下下一个函数。如果写成全局变量就能很直观看到他们三个是操作同一个东西了,如果是写成传参,并不能直观感受到。一个300行的代码,如果一直这么return和传参,读者脑袋就会伤不起了,效率就会下降很多。因为你写的不需要被import作为基础组件,也不需要多实例,那应该尽量多用全局变量。最好是多用三方包 多用三方框架,少自己写得一坨一坨的,不然接盘侠是肯定 看不懂的,因为框架规定了你怎么写,有约定俗成的在什么文件写什么代码,接盘者不需要去看你写的思路,因为大家对框架或者三方包都有共识。

因为看到一个代码写了3个函数里面的传参分别叫city  item region,但其实是操作同一个东西,写作者既不写参数类型注释又不写参数意义注释,在不同函数中起的名字又各种各样,然后不能表达出参数是一个字典,city 和region意思明显是一个字符串类似 北京 上海什么的,却让它表达的是一个城市字典信息,他要表达的是{'name':'北京','id':123},但用这个名字真的是日了狗,想搞清楚它必须一步一步的从函数调用处去分析它,调用不同函数的地方间隔代码行数太长,上一秒搞清楚了下一秒就忘了。所以一定要把名字起好,然后多写全局变量,例如本例中把这个城市信息字典写成全局变量,。不同函数操作的结果不需要return,需要return的直接修改全局变量,这三个函数不需要那么多次重复传参,因为函数可以直接引用全局变量。因为操作全局变量就很容易直观的看到函数到底在操作什么,如果使用函数传参,根本就不知道他要操作什么东西,必须跑到调用函数的地方去看(如果使用面向对象那就是操作实例属性了和这种方式的操作全局变量的思维差不多,但能很好地克服了既不用全局变量,也不需要频繁传参和return)。

3.1  关于多写全局变量 少return 少传参,说的是在单文件或者顶层运行文件时候,每个函数完成项目流程中的一个节点功能,是一环套一环的,这种模块也不需要被别的地方import。所以我并没有说一切函数都要按这么做,大部分作为被import的东西,都是完成一个很孤立的功能,比如怎么处理一个字符串,去掉它里面的什么字母,这个功能是孤立的,与其他流程并没有什么卵的关系,这种情况不适合少传参 少return,那肯定是需要把字符串传给函数,然后return消除了指定字符后的新字符串更合适了。

5、除了上面这个方式外,就是不要使用面向过程了,要学习面向对象和23种设计模式。

在学校学习嵌入式一期时候做过五子棋,是使用c语言面向过程做的,当时写了1300多行来完成这个项目,收尾时候老师说二期后学习c++后要用面向对象会更简单,但当时并没有把五子棋作为二期的任务,而是做音乐播放器移植到arm板。

关于面向过程和面向对象解决五子棋的流程:

例如五子棋,面向过程的设计思路就是首先分析问题的步骤:

1、开始游戏,
2、黑子先走,
3、绘制画面,
4、判断输赢,
5、轮到白子,
6、绘制画面,
7、判断输赢,
8、返回步骤2,
9、输出最后结果。

把上面每个步骤用分别的函数来实现,问题就解决了。
  
   而面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为:

1、黑白双方,这两方的行为是一模一样的,
2、棋盘系统,负责绘制画面,
3、规则系统,负责判定诸如犯规、输赢等。

第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。

可 以明显地看出,面向对象是以功能来划分问题,而不是步骤。同样是绘制棋局,这样的行为在面向过程的设计中分散在了总多步骤中,很可能出现不同的绘制版本, 因为通常设计人员会考虑到实际情况进行各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。

功 能上的统一保证了面向对象设计的可扩展性。比如我要加入悔棋的功能,如果要改动面向过程的设计,那么从输入到判断到显示这一连串的步骤都要改动,甚至步骤 之间的循序都要进行大规模调整。如果是面向对象的话,只用改动棋盘对象就行了,棋盘系统保存了黑白双方的棋谱,简单回溯就可以了,而显示和规则判断则不用 顾及,同时整个对对象功能的调用顺序都没有变化,改动只是局部的。

看见,即使不使用多态和继承,使用面向对象的思维来写五子棋,优势也是很巨大的。

python怎么写可读性好的面向过程的长篇代码?的更多相关文章

  1. python之迭代器、生成器、面向过程编程

    一 迭代器 一 迭代的概念 #迭代器即迭代的工具,那什么是迭代呢?#迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,因而不 ...

  2. python函数之协程与面向过程编程

    第一:协程 初步了解协程 def eater(): print('start to eat') while True: food=yield print('is eating food:%s'%foo ...

  3. python第四周迭代器生成器序列化面向过程递归

      第一节装饰器复习和知识储备------------ 第一节装饰器复习和知识储备------------ def wrapper(*args,**kwargs): index(*args,**kwa ...

  4. Python笔记_第一篇_面向过程_第一部分_2.内存详解

    Python的很多教材中并没有讲内存方面的知识,但是内存的知识非常重要,对于计算机工作原理和方便理解编程语言是非常重要的,尤其是小白,因此需要把这一方面加上,能够更加深入的理解编程语言.这里引用了C语 ...

  5. python之迭代器、生成器与面向过程编程

    目录 一 迭代器 二 生成器 三 面向过程编程 一.迭代器 1.迭代器的概念理解 ''' 迭代器从字面上理解就是迭代的工具.而迭代是每次的开始都是基于上一次的结果,不是周而复始的,而是不断发展的. ' ...

  6. python自动化开发-[第五天]-面向过程、模块、包

    今日概要: 1.内置模块 2.协程函数 3.递归 4.面向过程编程与函数编程 5.模块 6.包 7.re正则 一.内置模块 1.匿名函数lambda 定义:匿名函数通常是创建了可以被调用的函数,它返回 ...

  7. Python笔记_第一篇_面向过程_第一部分_1.Python环境的设置(含虚拟机)

    *Python环境的设置 Python的环境设置也就是所需工作平台的软件搭建.常用的搭建平台IOS系统+Linux系统和Windows+Linux系统的搭建.这里主要说明的是Windows+Linux ...

  8. Python笔记_第二篇_面向过程_第二部分_1.函数

    函数:这个词属于一个数学概念,在编程语言借鉴了这个概念,表现形式是一段程序代码的组合,也叫“程序集”.有过编程基础的人很容易理解这个概念,当我们编写程序越来越多的时候,程序设计大师们会把散乱的程序进行 ...

  9. Python笔记_第一篇_面向过程_第一部分_7.文件的操作(.txt)

    在平时,我们不光要对程序内的代码进行输入和输出的操作,还要对程序外的文件进行和语言之间的交换.操作和运算.在基础部分,先讲解对于外部的.txt文件的操作. 第一部分 基本内容讲解 1.   什么是文件 ...

随机推荐

  1. Vagrant (2) —— 基本安装与配置(下)

    Vagrant (2) -- 基本安装与配置(下) 摘要 基本安装与配置 版本 Vagrant版本: 1.8.1 内容 预置 我们可以通SSH登录然后安装一个web服务器,但是这样每个使用Vagran ...

  2. jQuery(十一):jQuery的事件

    一.jQuery事件的分类 jQuery事件是对JavaScript事件的封装,常用事件分类如下: 1.基础事件 window事件. 鼠标事件. 键盘事件. 表单事件. 2.复合事件是多个事件的组合 ...

  3. github fork 同步

    git remote -v git remote add upstream url git fetch upstream git checkout master git merge upstream/ ...

  4. Bootstrap 里的 popover 被挡住的解决方案

    在Bootstarp 中我们可以使用 popover 插件做一些内容的展示, 代码如下: <a data-toggle="popover" data-placement=&q ...

  5. 解决android studio上“com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65935”问题

    我是在更换应用的一个jar包时发生的这个错误,网上查到说是因为同时在工程中引入了多个第三方jar包,导致调用的方法数超过了android设定的65935个(DEX 64K problem),进而导致d ...

  6. [Intellij] 软件设置和常用快捷键

    理解Project 和 Module 一个 Project 是由一个或多个 Module 组成,模块之间尽量是处在同一个项目业务的的情况下,彼此之间互相依赖关联.如: Project : spring ...

  7. Ubuntu 安装软件方法

    Ubuntu软件安装有几种方式,常用的是deb包的安装方式,deb是debian系列的Linux包管理方式,Ubuntu软件安装属于debian的派生,也默认支持这种软件安装方式,当下载到一个deb格 ...

  8. ThinkPHP使用memcache缓存服务器

    (1)Thinkphp的默认缓存方式是以File方式,在/Runtime/Temp 下生成了好多缓存文件. 服务器装了memcached后想给更改成memecache方式 在Conf/config.p ...

  9. mxnet卷积神经网络训练MNIST数据集测试

    mxnet框架下超全手写字体识别—从数据预处理到网络的训练—模型及日志的保存 import numpy as np import mxnet as mx import logging logging. ...

  10. Android多国语言的value文件夹命名方式

    在res目錄下建立不同名稱的values文件來調用不同的語言包Values文件匯總如下:中文(中國):values-zh-rCN中文(台灣):values-zh-rTW中文(香港):values-zh ...