你真的会python吗?

声明:这篇文章转自http://www.dongwm.com/archives/ni-zhen-de-hui-pythonma/,我看后颇有当头棒喝之感,故收于此顺便修改几处错字,十分感谢原作者!

前言

我这个博客一直都是一些技术分享,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的架构.我认为对于现在项目状态,我要思考大约未来一年可能的发展,它如何简单的扩展就好了..