聊聊我对python的感觉

工做中主要是在写python2,把python做为用户逻辑的载体的,通常是C++写好底层,导出成python模块使用,或者是可执行程序带起来一个python虚拟机,把函数注入进去,而后加载python代码执行。我接触的这部分python,没有太多的框架,几乎不使用基本数据结构以外的标准库,由于不少东西都是C++封装好给python的,性能比纯python好不少。所以下面的文字也主要围绕着我使用的这个python的子集展开,若是有所误差,那也是没法避免的。python

python的一些优势

hook一切的能力

python的装饰器提供了一种在定义处直接修改被定义的对象的能力,有点相似清洁宏。宏这种东西,目的就是对语言的语法树作变换,生成被调整过的语法树结构,来达到抽象某些东西的意义。然而大部分加宏,尤为是清洁宏的语言,都不可避免的要考虑一个问题,就是如何表示语法树和语法树的变换。Lisp系由于自己代码就是数据,因此语法树,代码,变换都是S-expr;rust则是发明了另外一套语法来作这一件事情;还在proposal阶段的C++ reflection,不只要发明语法,还要发明对应的库和namespace,甚至还要和constexpr之类的东西耦合,这就很丑,并且又很大地增长了语言的复杂度。不喷C++了,python的装饰器很巧妙的复用了python语法,经过放弃一些变换的自由度的方式(装饰器只能以函数/类为单位进行变换)实现了较为舒服的宏。数组

另外一个要说的就是metaclass,metaclass用来hook类型的建立,能够用来作一些在类型建立时对类型进行调整的工做,好比增减类变量,修改基类,注册一些东西,变换一下函数等等。数据结构

最后就是属性索引器__get__和__set__,我曾经在看到他们以后忽然意识到,这就是C#的DependencyProperty须要的东西,不经过用户编写代码,来达到hook一个属性的读取和写入的能力。写过WPF的同窗都知道,WPF里面有一套很复杂的DependencyProperty/Object系统,其实说白了就是须要hook属性更改,用来作数据绑定之类的东西,写起来很麻烦,VS也专门提供了插入dependency property定义的boilerplate的功能。python这个属性索引器设计就很好的解决了这个问题,至少让代码写起来没有那么多废话了。框架

有人可能以为我用C++和C#跟python对比不合适,的确,这些语言的主战场是大型系统,高性能,硬件抽象,的确不适合用来实现过于灵活的东西。函数

不吝于用开洞的方法来解决问题

python有不少魔术方法,并且随着语言的进化,还在加入更多的魔术方法。对象构造走魔术方法,运算符重载走魔术方法,上面说的hook属性索引器也是魔术方法,甚至检查一个类是否是另外一个的基类,也能够走魔术方法。当语言层面原生为你提供不少hook的时候,尤为是须要灵活性的动态语言,他的灵活性就真的有了。反观C++一直在吹嘘咱们能够用抽象来实现一切东西,而后写出来的东西都是一坨一坨的模板,而后initializer_list,structured binding,attribute仍是忍不住开了洞。C#这样语法还算很优雅的语言,也须要一堆boilerplate来作dependency property。固然他们都是静态语言,主战场是性能,原本就不该该和动态语言相比较。性能

另外一个要说的就是__getitem__和__setitem__,python的obj[key]和obj[key]=value走了两个不一样的方法,这样就很棒地绕开了key不存在时究竟是要添加,仍是丢异常的问题。由于分开了读取和写入,obj[key],不存在丢异常,obj[key]=value,不存在就添加,和C#/C++的Dictionary/map设计相比好了很多,这俩一个不存在都丢异常,一个不存在都添加。优化

与C++杂乱的开洞相比,python的洞基本都开在魔术方法上,位置相对比较统一。spa

python的垃圾之处

智障缩进/换行语法

强制缩进,换行,python是惟一一个lambda会下降代码可读性的语言。就没据说过其余哪一个语言的lambda会让代码可读性变差的设计

强行换行用\,尤为是当if条件稍微长一点的时候,你不想用\,把if拆开,就得缩进好几个tab,你用\换行,看着就跟C++写了一坨宏似的对象

基本控制流太少

虽然传统的for、do-while均可以变换成while来作,可是while True: if xxx break很丑哎,加个do-while又不会怀孕

虽然switch能够用dict+lambda作,但lambda都那么丑了,我又不想白白产生一个构造dict的overhead,只能写一坨if else

真的慢,没有jit,没有内联优化,没有逃逸分析,对象全都开在堆上,引用计数+mark sweep也慢,处理个数组能比C++慢两个数量级,小函数调用特别伤。

相关文章
相关标签/搜索