前言

我这个博客一直都是一些技术分享,show code 的地方,我从来没有写过个人生活或者情感杂谈,当然我也从来没有谈论过我对什么东西的喜恶. 很多人喜欢喷 XX 语言,喜欢谈论 XX 和 YY 的优缺,甚至凑了一本不知所云的书... 好吧,我觉得没有使用一门语言超过 10 年,没有对一个技术研究个 5,6 年, 不好意思说自己懂 (天才除外). 我也觉得我没有资格讨论什么,也许我有我的观点看法,但是我怀着怀疑的心态看自己,生怕自己理解错了. 下文纯属个人吐槽,也许没有指定路怎么走,只是希望提个醒...

使用 python2 年,可喜的是 python 被越来越多的人接受,甚至前端工程师... 但是却有点烂大街的感觉:感觉出门不聊几句 python 都不好意思和人打招呼。但是你真的懂 python 嘛?

你会 python 真的不重要

python 实在太好学习了,假如你会其它的语言,可能搞本书翻一翻,一周后就能写很高端的 python 程序,由于 web 框架的普及,你甚至可以让一个网站应用跑起来。你会我也会,你有什么竞争力?

你知道 python 怎么用嘛?

  1. 在什么时候需要使用 OOP?
  2. 在什么时候使用类装饰器?
  3. 你用过元类嘛?
  4. 在什么时候用静态方法什么时候使用类方法?
  5. 你了解那些管理属性?__call__ , __init__ , __new__ 都是在什么时候被触发?__getattr____getattribute__ 应用有什么不同?
  6. 你知道标准库里面的多少个模块?你能在需要的时候知道这个功能其实标准库里面已经实现了?
  7. 什么时候用回调?
  8. 什么时候用 signal?假如你会 django 你知道 django 的 signal 是什么?你了解 orm 嘛?
  9. asyncore,contextlib, functools, collections, heapq,itertools, SocketServer, weakref,operator (知道 3 个就算) 这些你会几个?
  10. python 的多态是什么?
  11. 在什么场景可以尝试 python 的设计模式中的 XX (能想到 2 个场景就算)?
  12. 在什么时候可以使用 Mixin?
  13. 在什么时候可以使用 python 的闭包?
  14. 你曾经用过 yield 嘛?生成器和迭代器的区别和应用场景是什么?
  15. 在什么可以使用 python 的函数式编程?
  16. future 模块里面都有什么定义的用法?

提笔想了这上面 16 点我认为体现 python 的东西,假如你不能有效的回答上面 1/4, 好吧不要和我说你原来是会 python 的,踏实下来.. 你的路还很长。假如你回答不超过一半,我提醒你 - 你只是刚入行而已 (这是我的角度)

假如我是一个入职后的带新人的引导者

  1. 学好 git... 呵呵
  2. 假如新人还不熟悉 python,python_koans 是个不错的入门选择
  3. 首先就是严格的代码规范,加上团队的文化以及风格.
  4. 我会给一个任务,比如一周内写个多线程的 socket 命令行聊天程序,支持群组,加好友,群聊,发送文件等功能,看新人能力而定
  5. 而后把项目一部分略棘手的工作教给他,注意这里是生产环境,在他完成任务的过程中会熟悉我们的上线 /code review / 代码风格等东西
  6. 我希望整个团队一起贡献一个基础的公共库,包含一些常用的功能,然后新人首先学习这些东西,以后就不需要浪费时间造轮子,但是可以修改完善公共库, 这个公共库可以在新服务器部署时候直接使用 pypi 或者 ubuntuPPA 安装进来

什么算是好的 python 代码?

假如你的代码没使用 pep8 检验过,你.... 最差你也要使用 autopep8 格式化差劲的代码吧?如果你想对自己的代码质量有要求,我强烈建议你了解什么是 pythonic:

  1. doughellmann ( 的作者) 的 an-introduction-to-the-zen-of-python
  2. be-pythonic

代码易懂但是堆了很多 / 代码难懂但是精炼之间的取舍

我想很多对代码有追求的人,会看见项目中存在大量,没有被重用的函数,似曾相似的方法甚至方法的名字... 我是极为见不得 ugly 或者华而不实的代码的人,但是有个问题。我封装的代码很不直观,难懂.. 原来的代码貌似极为好懂。每个人都有自己的理解吧。就象我的团队里面有人说 django 代码太难懂,因为它们有 django 项目组的文化... celery 代码写的不好这样的安慰似的评论... 但是我不这样认为,我还在读 celery 代码,我也承认里面是有作者风格的取名或者实现的方式,但是我学到了很多.

通过看开源代码,比如 django,requests,flask. 我会发现和总结很多别人的用法,思考别人为啥这样用。比如项目代码目录结构,解决一些问题使用的方式。还有一些 pep8 中没有提到的规范。比如一些代码实用的风格,举个例子:

我们的代码引用其它模块是这样的:

from test import long_long_long_test1
from test import long_long_long_test2
form test import long_long_long_test3

省略 20 多行,很脑残吧?有一种风格是

from test import long_long_long_test1, \
                 long_long_long_test2, \
                 long_long_long_test3

说一个技巧:当我不知道该用什么,去看很 NB 项目怎么用 结果 django 和 requests 是这样的风格

from test import (long_long_long_test1,
                  long_long_long_test2,
                  long_long_long_test3)

怎么样进步?不是闭门造车.. 先去看看别人是怎么用的..

比如我以前拼接一个文件路径都是这样:

'{0}/{1}'.fotmat(dir, filename)

其实人家本来有:

os.path.join(dir, filename)

很惭愧。然后花了半个小时,把以前我这样用的地方全改了

这是我说的重要的一点:知道了什么是对的 就要改....

对于这个主题,我的答案是:我喜欢难懂但是精炼的代码。境界就是你看的懂就能写的出来. 假如你连这点代码都看不懂。你看不了开源项目的做法。你会一直是个堆代码的码农.. 你会一直在堆着垃圾的代码。你会增加未来接手人的维护成本

怎么样提高 python 可读性和质量

以下是我的想法

  1. 首先给函数 / 类 / 方法取个好懂的名字 (我这点很失败,英语太烂... 是不是应该加一个学好英语)
  2. 当一个差不多的操作出现了三次,不要继续堆代码,要抽象出来
  3. 我倾向于写 FIXME,TODO, 写文件 / 函数的用途的注释,在不是很好理解的代码上面注释作用,标明输入和输出都是什么 (如果不是要修改维护你的代码,没人在乎你的算法多 NB)
  4. 上面说的,请不要让别人需要仔细研究你的代码才明白是什么意思.. 我写代码很有压力,因为我不想以后维护我代码的人骂我.
  5. 不要炫技,请不要乱用函数式编程 / 闭包。我在乎的是性能和简单粗暴的实现功能
  6. 多用标准库的实现,如果不知道有这个功能实现前先 google.
  7. 多读有名的项目,github 上面有很多。思考别人为什么这样用

....

我们是封装开源项目还是直接修改开源代码给自己用

其实我这样描述,比如有个项目因为历史原因是一个很早的版本。但是和其它新的版本组件有兼容问题以及我们业务的特殊需要。我看了源码发现需要改动几个地方. 问题改动后就需要自己维护这个项目,对于新部署的环境甚至其它版本我还继续需要这个变动。还有一种声音是 "你不能修改 XX 源码", 你要在上面封装出一个新的东西, 也就是不直接调用 XX,而是在我的自己的项目对 XX 有了个封装 YY,然后我们的调用 YY.

我觉得这个东西自己部署是一个可行的方案,首先这个修改不是一个 patch,不是主流的修改。只能算是我们业务的二次开发而已,封装只是在掩耳盗铃. 着让我想起一个问题:为什么中国鲜有好的开源项目:中国人不缺好的 idea? 是因为中国人觉得这件事情做不了,是因为它们觉得别人实现的就是很牛比的, 自己改了就会有问题... 其实这是自卑.. 首先是代码就会有 bug,tornado/flask/requests 不还是在开发和解决问题嘛?bug 一直在只是你没有发现和注意. 我觉得开源项目的代码看懂了,了解了就可以修改.. 没什么可担心的... 我指的是角度。我觉得每个人学了一门语言看了某个项目的源码只要你有胆量, 你有一个怀疑的善于发现和思考的心,那么你都能贡献你的代码,做你的二次开发.

和本文相关:如果你没有做过这件事,你怎么可以说你会 python?

我的感想

我不赞同 "做好工作就好了" 的调调。对你个人来说你明年今天做的事情和现在是一样的,不同的是你老了一岁. 如果是为了完成工作而完成工作。其实你这个代码就是线上运行的代码,并且是以后很长时间再用的版本,你随意的一些代码会在很久之后很难的变动.. 我也不同意一上来就把你的程序写的能承受千万级 PV 的架构。我认为对于现在项目状态,我要思考大约未来一年可能的发展,它如何简单的扩展就好了..