@@ -176,7 +176,7 @@ python代码坏味道(新手经常犯的错误)
176176测试相关:
177177
178178- 没有单元测试,不知道怎么写测试(print大法好?)。没有一点专业精神,或许和python大部分都是自学的业余选手有关。
179- - 不专业,写了几句代码print下结果就觉得正确了,单元测试呢?docstring呢?代码易用性和可维护性极差,未经测试的代码是不值得信任的。
179+ - 不专业,写了几句代码print下结果就觉得正确了,单元测试呢?docstring呢?代码易用性和可维护性极差,未经测试的代码是不值得信任的。不要太相信自己,人总会犯错。我经常调试别人写的未经测试的代码。
180180
181181嗯,一开始就开启pep8和pylint检测能显著提升代码质量(各种错误警告逼着你写出规范的代码)。咱写不了诗一样的代码,也不能写shǐ 一样的代码,维护一个ugly的代码仓库能有效减少你的寿命。可能很多东西对老鸟来说都是显而易见的,不过菜鸟和高级菜鸟们还是需要多多练习积累经验。慢慢摸索吧骚年。。。。。。
182182
@@ -196,7 +196,7 @@ python代码坏味道(新手经常犯的错误)
196196 return testranking > topranking;
197197 }
198198
199- 上面是一段java和python的对比,用来说明为什么python难以维护。java版本一眼就能看出来传入参数的类型和返回值,但是遗憾的是python看不出来,在python中基本只有通过docstring你才能知道传入参数的类型。当项目大了以后,维护一份没有文档和注释的python项目基本就是灾难。笔者曾很喜欢python语言,认为python是“伪代码”语言,但是有了维护python旧代码的经验后,我开始怀疑python是不是适合构建大型项目。当然很多知名应用是python构建的,我觉得老外们软件工程做得还是不错的,把控好代码质量和单元测试(比如Quora创始人曾经解释过他们为什么选择了python)。但是我经历的一些使用python的项目工程方面却比较糟糕,代码维护起来非常吃力,开始让我对python产生严重怀疑。java虽然写起来繁琐,但是不容易出错,动态语言写起来爽,但是维护和重构起来吃力,并且容易出错。我个人感觉就是使用动态语言要严格把控代码质量和文档,用好pylint对代码静态检测。
199+ 上面是一段java和python的对比,用来说明为什么python难以维护。java版本一眼就能看出来传入参数的类型和返回值,但是遗憾的是python看不出来,在python中基本只有通过docstring你才能知道传入参数的类型。当项目大了以后,维护一份没有文档和注释的python项目基本就是灾难。笔者曾很喜欢python语言,认为python是“伪代码”语言,但是有了维护python旧代码的经验后,我开始怀疑python是不是适合构建大型项目。当然很多知名应用是python构建的,我觉得老外们软件工程做得还是不错的,把控好代码质量和单元测试(比如Quora创始人曾经解释过他们为什么选择了python)。但是我经历的一些使用python的项目工程方面却比较糟糕,代码维护起来非常吃力,开始让我对python产生严重怀疑。java虽然写起来繁琐,但是不容易出错,动态语言写起来爽,但是维护和重构起来吃力,并且容易出错。我个人感觉就是使用动态语言要严格把控代码质量和文档,用好pylint对代码静态检测,否则项目大了难以维护 。
200200
201201重视细节
202202--------------------------------------
@@ -236,7 +236,7 @@ python代码坏味道(新手经常犯的错误)
236236
237237 """
238238
239- 这个是google的docstring示例,是我比较推崇的一种格式。还是那个问题,动态语言没有类型声明,所以复杂函数要在docstring里写清楚传入参数和返回值的描述和类型。良好的docstring能让维护代码的人一眼就看明白这个函数是怎么使用的,即使内部很复杂,也尽量保持接口简单,容易使用。
239+ 这个是google的docstring示例,是我比较推崇的一种格式。还是那个问题,动态语言没有类型声明,所以复杂函数要在docstring里写清楚传入参数和返回值的描述和类型。良好的docstring能让维护代码的人一眼就看明白这个函数是怎么使用的,即使内部很复杂,也尽量保持接口简单,容易使用。经常有人传出个嵌套字典(dict的key是主键,每个key对应的value里还有字典),这种相对复杂的数据结构还不注释,每次看这种函数都要打断点看返回结构。这种就是典型的接口易用性差,只在意实现功能,完全不管别人使用,合作起来比较心累。
240240
241241- Docstrings = How to use code
242242- Comments = Why & how code works
@@ -280,14 +280,14 @@ Code Review
280280
281281日志与异常记录
282282--------------------------------------
283- 一定要有良好的日志记录习惯。良好的日志对于记录问题至关重要。python有方便的日志模块帮助我们记录,日志输出的代价是比较小的,python的日志模块尽量做到对函数功能没有性能影响,可以在线上和开发环境设置不同的log等级,方便开发调试。注意别再日志语句里引入了bug或异常。
283+ 一定要有良好的日志记录习惯。良好的日志对于记录问题至关重要。python有方便的日志模块帮助我们记录,日志输出的代价是比较小的,python的日志模块尽量做到对函数功能没有性能影响,可以在线上和开发环境设置不同的log等级,方便开发调试。注意别再日志语句里引入了bug或异常。有时候需要判断什么时候需要日志,记录哪些东西方便我们排查问题,分析数据。
284284对于异常,一定『不要吞掉任何异常』,常有新手上来就try/except,也不区分非退出异常,也没有日志记录(坑啊......)。请先阅读python文档的异常机制,可以使用Sentry等工具记录异常。同时发生异常时候的时间,调用点,栈调用信息,locals()变量等要注意记录,给排查错误带来便利。有些错误的复现是比较困难的,这时候日志和异常的作用就凸显出来了。
285285
286286* `《每个 Python 程序员都要知道的日志实践》 <http://mp.weixin.qq.com/s?__biz=MzA4MjEyNTA5Mw==&mid=2652564362&idx=1&sn=f33910af004f276bbef7ae52e0757bcb&chksm=8464c3c0b3134ad617bcffd865894344367fdd2995a0d5ff9c4da30e0c158b3d02b3d616f615&mpshare=1&scene=23&srcid=1124K7Ht1FP2A1Fnvi3HTBE5#rd >`_
287287
288288调试
289289--------------------------------------
290- 调试也是个很重要的问题,不可能保证代码没bug,要命的是有时候写代码完成功能的时间还没调试的时间多。注意复现是排错的第一步,之后通过各种方式确定原因(访问日志、邮件报的异常记录)等,通过走查代码、断点调试(二分法等)确定错误位置,确定好错误原因了就好改了。修复后最好反思下问题的原因、类型等,哪些地方可以改进,争取下次不犯一样的错。
290+ 调试也是个很重要的问题,不可能保证代码没bug,要命的是有时候写代码完成功能的时间还没调试的时间多。注意复现是排错的第一步,之后通过各种方式确定原因(访问日志、邮件报的异常记录)等,通过走查代码、断点调试(二分法等)确定错误位置,确定好错误原因了就好改了。修复后最好反思下问题的原因、类型等,哪些地方可以改进,争取下次不犯一样的错,慢慢减少错误才能越来越高效 。
291291
292292* `《调试九法》 <http://www.wklken.me/posts/2015/11/29/debugging-9-rules.html >`_
293293
@@ -297,7 +297,6 @@ Code Review
297297最后,很多东西我也在摸索,上面的玩意你就当小白的踩坑记录,随着理解和经验的加深我会不定期更新本篇内容。另外我发现网上大部分是教程性的东西,对于python相关的工程性的东西很少,我很疑惑难道大部分公司的python项目都写得相当规范?没人吐槽?反正我是踩过坑,希望看到过本章的人能把python代码质量重视起来。
298298
299299
300-
301300最后来,跟我一起大声朗读《The Zen of Python》
302301
303302::
0 commit comments