python or not python
python or not python
我挺喜欢 python 这种编程语言,它本身的丰富的动态特性让这种语言的表达能力很强,基本上 python 上写的一行代码,可实现 java 上 1.5 到 3 行左右的功能。它上手是挺容易的,照着帮助文档学,大概两天左右,有编程经验的人就能把语言的大部分特性学会。
但要注意的是,学会 python 并不意味着能用好 python ,特别是在大型多人协作的项目上。
有以下几点是必须要注意的:
缺乏的有效静态类型检查,需要精心设计单元测试
python 是一种动态语言,本身在静态类型检查等方面缺乏有效工具。采用 python 的项目,都要特别注重单元测试,防止引入了很低级的错误。我曾经遇到过把对象当成了函数,而且在单元测试都没有发现出来,因为这个对象本身被弄成了 callable 的,直到性能测试时,才在日志中发现了这个问题。
接口的概念较弱,设计时和工作分解时有难度
动态语言强大的动态类型有时给设计工作带来很大的麻烦,在设计时我们期望接口是明确目标的并有限制功能的,每一个参数应该是预定义的,而实现时很难限定传入的对象类型。同样的一个接口,不同的人很容易产生不同的理解,因此除非实现者已明确了函数的设计内容,以及它在整个解决方案中的作用,否则就会出现各种各样的实现。上面 callable 对象是其中一个例子,还有一个隐藏得比较深的例子:
某个接口函数 add_callback
需要一个回调函数,这个函数只有 async_result 作为参数,用于在异步调用结束时进行处理。但是为了处理一些额外的参数,于是出现了一个代码,大概如下:
...
for i in range(100):
def f(async_result):
dosomething(i)
dosomething(async_result)
a = A()
a.add_callback(f)
a.start()
...
还有人这样处理了:
def wrapper(i):
def f(async_result):
dosomething(i)
dosomething(async_result)
return f
...
for i in range(100):
a = A()
a.add_callback(wrapper(i))
本来,这应该是属于接口设计上的问题,但是却被通过不同的方法"巧妙"地掩盖了起来。
缺乏足够良好的可参考实践和标准
在实际的项目中,除了强制的缩进,不同的人很容易写出不同的代码风格!
在doc_strings上,python并没有规定注释的标准格式,因此有多种实际使用中的注释方法。
在大型项目方面,目前很少见到用python来编写,可能是目前还不是太多团队会采用 python 。但这点正在变化,像 OpenStack 这样的大项目基于 python 编写,很多工具也支持 python 接口。
由于动态语言的关系,python 在创建一个具有自己特色的框架方面会显得相对容易。因此,python的框架总是一大堆的,django / flask / web.py 之类的框架,每个都很有特色,选择起来容易头痛。
python or not python
这个问题,应该综合开发组实力,以及开发项目的规模、后期维护等因素综合考虑。
如果项目的规模不算大,而且成员都有一定的 python 编程经验,那么在限定编程规范时,还是值得使用 python 来进行快速迭代开发。如果项目大,接口多而复杂,就不建议采用 python 了,这种项目后期的维护工作量大,需要了解项目结构和设计的人才能继续维护 python ,还不如用 java 一些成熟的方案。
python 用得好,能很快建立系统原型,并在后续的开发中进行持续的迭代改进,比使用 java / C# 等要更快能实现一个可运行原型,而且代码量有显著的减少。python 的生态链越来越丰富,将来完善了各项支持工具,或者会有更多的项目采用 python,让它进行良性的发展循环。