之前听到过别人有说过Python只是一个玩具做不了大项目,我当时是嗤之以鼻的,不说豆瓣这样的公司采用Python做的网站,GitHub上那么多大项目都是用Python写的,怎么能说Python只是一个玩具呢。直到我参与维护一个Python项目。

弱类型

一般都说Python的弱类型是程序员的福音,程序员能够更灵活的控制代码,但问题是你在写代码的时候是灵活了,你想过日后维护没有,特别是那些没有注释的代码。基本上项目里面各种类型的变量随处定义,而且有的变量类型不知道什么时候就改变了。

我之前遇到过这样一个错误,报的异常是int类型没有某个方法,我定位到对应的代码处,发现他是由函数参数带进来的一个变量,当时又没有声明,完全看不出它是一个什么类型,但是从函数的逻辑上看应该是一个自定义的类型。而且我在对应位置下断点的时候完全没有问题,而且后续出现的几率比较低,既然调试不了,只有一层层的查代码了。根据函数的调用顺序,我终于找到了它的结构。当时是查询数据库然后给返回了一个结构,只有当查询失败的时候会返回一个-1,但是当时写程序的那个家伙没有对这个-1做校验,而且失败基本上是不会出现的,至今我也没有弄明白为什么查询会失败,只是加了一个校验做了一下其他的处理,这个问题就解决了。

这个时候我就深深的体会到弱类型语言在后续维护的恶心的,如果是一个强类型,在定义了类型就不会出现什么类型变了的情况。

强制缩进

这也是一个我觉得恶心的地方,作者的原意是好的,希望能写出更规范的代码。但是当时在维护的时候我习惯用vim,之前的代码不知道用什么写的,我习惯用4个空格,之前的同事可能习惯用tab键,于是灾难就发生了,从vim里面看,完全看不出那些是空格那些是tab,后来我直接使用替换将所有tab替换为4个空格。

强制缩进还有一点就是函数代码一旦很长,嵌套稍微深一点,从维护上看完全看不出来哪块是哪个语句块的东西,而且它不支持{},一般根据{}可以很方便的判断。

还有一个问题就是嵌套层数深了对于我们这些空格党来说敲的字符也就变多了,有的地方不明确的还得数着敲,一层嵌套是4个,两层8个,三层12个,用不了多久你就崩溃了

独立特性的加载方式

相比于C/C++的include ,Python采用import来加载所需要使用的库,对于C/C++来说加载库就仅仅是将库中的代码加载到进程的地址空间中,什么时候执行什么操作完全由用户自己控制,但是Python在你加载库的时候会默默的帮你执行初始化函数,平时是没有什么问题的,但是一旦你定义的变量与库中的相关内容重名的时候,灾难就来了,如果不是有百度、google这些搜索引擎可能我早就怀疑我的Python有问题,在重装无果后大骂Python并最终弃坑了。

如果在代码中出现

import numpy as n
这样的语句估计会被维护的程序员当场击毙

库命名的随意

Python的库一般以Py开头,比如说PyPy、PyPi、PyGame。但是也有Py在后面的,比如NumPy、SciPy,SymPy,还有不带Py的,比如常见的requests,Pillow, matplotlib, SQLAlchemy, 这些至少你能从名字上判断它是干嘛的,像BeautifulSoup这样的,打死都猜不到它竟然是一个XML解析库。

库中使用的类、函数、全局变量也很随意,如果没有搜索引擎,我是绝对猜不到cv2 是opencv里面的东西

安装也是一个麻烦,虽然大部分都可以使用pip 安装但是比如说你使用 pip install Django,事先好像不知道它适应与哪个版本,这也是不同Python版本不兼容带来的,还有像python-opencv python3-opencv,既然有的能根据Python版本来正确安装,为什么有的不行,非得指定的那么详细。

拷贝与赋值的问题

这个问题特别是在函数中间问题最大,一般的语言中值传递是不能修改实参的值的,但是在Python中,向字典这样的它就可以,而像list这样的好像不行,说实话至今我都弄不明白为什么,也记不住类型的可以哪些不行。而且它的深拷贝和浅拷贝我觉的跟其他语言差距很大,理解起来有点困难。

最后再说一句

吐槽了这么多,我并不是要完全否定Python,不得不说Python是一门非常简单实用的语言,而且社区强大,拥有各种功能的第三方库,说句夸张的,除了生孩子,Python能做任何事情。

当然这些问题只是我对Python的理解不够,我也只限于实用它,而没有做到熟练或者精通的地步,这些问题可能在一些更Pythoner的程序员手中根本不是问题。

不知道在哪看到这样一句话,没有烂语言,只有烂人,当你写不出足够优雅的代码时,留给后续接盘的人的只有一地鸡毛,各位程序员且行且珍惜

05-11 11:22