##language:zh #pragma section-numbers off ##含有章节索引导航的 ZPyUG 文章通用模板 <> ## 默许导航,请保留 <> = Py的缺点?! = ##startInc == 提问 == {{{ Zoom.Quiet zoom.quiet# gmail.com 发件人当地时间: 发送时间 14:24 (GMT+08:00)。发送地当前时间:下午5:03。 ✆ 主题: [PyCon2011China]后续思考: Py 有什么缺点?! }}} 在昨天内部分享交流中,俺回顾了 `PyCon2011China` 中透露出的 Py 最新使用/发展和体验; 最后有同学问: Python 有什么缺点!? 直接HOLD 住了俺的思路... {{{ - 是也乎!? - 世界上没有完美的语言 - Python 相比各种开发语言也有缺点,当然的! 可是,是什么呢?! - 没有 {} ? - 不支持多CPU ? }}} 大家在学习使用过程中,对 Python 有什么失望的地方?! - 兼听则明 - 现在不满意的,就是我们努力的方向.. PS: - 俺现场憋出的回答是: - 由于 Py 历史上积累的好用模块太多,会导致开发人员更加懒惰,不思进取,不论什么都可以直接搜出可用的现成模块来! == 总结 == {{{ sj l shuxiang29 # gmail.com 发件人当地时间: 发送时间 10:36 (GMT+08:00)。发送地当前时间:上午10:46。 ✆ }}} 好吧做个总结,大家继续增补,为了更好的Python! 严重的: * --(1. 我们需要BLOCK,强烈需要)-- ~ 縮进比什么都好! * 2. GIL * 3. 编译打包 * 4. py2到py3的兼容 * ~Lan Soda he # xxoogo.com * 变革就是要牺牲短期利益获得长期利益的,你可以选择用py2来写程序,也可以选择py3写,或者是重构。如果py3对py2无缝兼容了,那还搞py3有什么意义呢?就像c++对c的兼容性确实好,但是c++包含了所有c遗留下来的诟病,所以c++并不能根本上解决c的致命问题,同时又徒增了复杂度,而且c++是反紧凑性的,其发明人已经坦言不指望任何一个程序员完全理解c++。大部分写c++程序的人只是在用c的语法写c++。你们希望看到人们用py2的不良特性写着py3下面能跑的程序吗? * 5. accsi字符串而不是unicode,特别是操作文件系统的那些函数,搞死你 * ~Lan Soda he # xxoogo.com * 我认为字符串这个概念,就应该是unicode的,不分什么ascii,gb2312,utf8的,因为字符串就是“文字”!py3在这一点上做得很对! * 6. 多线程并发(支持native thread是个错误) * ~Lan Soda he # xxoogo.com * 引用一句都知道的大牛说的话“线程是那些进程生成代价昂贵,不支持简单RPC的系统上的废品。它需要彼此间依赖过多的状态标志和底层细节”。你想获得优良的多核性能,就在UNIX/Linux下面设计多进程程序!而不是要求py去完美支持这些微软搞出来的烂概念! * 7. 既然`__eq__`为神马`__ne__` * 8. classobj与type这两个东西确实该去掉一个,鸡乎?蛋乎?(Python 3去掉了classobj)----这货太绕口令了 * 9. 区分表达式和语句(我开始喜欢万能的lisp了), 我们需要(foo = []).append(42) 而不是foo = []; foo.append(42) * ~Lan Soda he # xxoogo.com * 我不觉得foo = []; foo.append(42)有什么不好,至少从代码可读性上来讲。代码大全里也提倡,应该把一行物理单元只对应一行逻辑单元,这样代码的可读性才会更好! * 10. 弱到不能再弱的lambda,py3的更弱 * ~Lan Soda he # xxoogo.com * lambda这个东西,可以用普通函数替代,而且个人感觉,lambda用多了,会让代码的可读性很低。py不是lisp,更不是图灵机! * 11. closure * 12. 操蛋的文档,参数什么类型,返回值什么类型,会不会抛异常,抛神马异常都大多都木有说明 * 13. 操蛋的元编程,反正我看不懂 * 14. 操蛋的OO实现(比如logging库操蛋) * 15. 木有用的库在标准库中一堆(xml,sgmllib,HTMLParser...),最有用的库不是标准库中(chardet,...),清理!!! * 16. unix socket性能不好,sendfile都木有,支持不完整(比如库readline,ncurse) * 17. 木有标准的IPC函数 * 18. fucking local domain,我脑细胞twisted了,另外py3加nonlocal的方案也太难看了~,不能搞成lisp的env那种吗? * 19. easy_install 不强,pip也还不够好(看看apt!) * 20. 沙盒不够好 * 21. 协程的支持也是个问题,py3虽然很快会支持yield from,可是这货的体验根本没法跟greenlet比 * 22. 正则表达式不支持Unicode-aware regular expressions * 23. dict,list这些不能被subclass,抓狂呀 * 24. 糟糕的库命名(copy.copy, 而不是copy, BaseHTTPServer而不是http.baseserver,UnitTest.assertEqual,而不是UnitTest.assert_equal例子太多了!!!参考pep8) 其它的不爽利: * 1. 性能,这个一般不是问题 * 2. 多核,反正线程使用很纠结,多进程来吧(通信麻烦些?) * 3. IDE * 4. 嵌入到C麻烦 * 5. 商业支持少 * 6. 尾递归优化,龟叔的说法是为了更好的异常回溯 * 7. ''.join(),这个我不同意 * 8. 框架多,我觉得不是问题,因为wsgi太简单了,大家都能写出框架是很好的 * 9. 手机app开发不给力,木有像 pyqt那种货呀(貌似meego有?) === zw g === {{{ zw g pekingmaster# gmail.com 发件人当地时间: 发送时间 14:55 (GMT+08:00)。发送地当前时间:下午5:04。 ✆ }}} * 1)iOS, Android等移动设备的App开发目前感觉不给力 (不是指web的方式) * 2)性能 * 3)多核? * 4)GIL? * 5)编译打包流程 === Leo Jay === {{{ Leo Jay python.leojay# gmail.com 发件人当地时间: 发送时间 14:58 (GMT+08:00)。发送地当前时间:下午5:05。 ✆ }}} 我不同意说python没缺点。但我也不认为python3是一次大修。 在我看来python3最重要变化,一是print之类的语句变成了函数调用,二是默认使用unicode做字符串。 这能算是大修么?至少我个人认为是不算的。 从我的角度来说,python可以提高的地方, * 一是运行速度,目前还远不能跟编译型语言比, * 二是IDE,还没哪款python的IDE能达到intellij idea和eclipse对java的支持 * 三是多线程并发执行的支持 至于语言本身,我没感觉到有什么明显的缺点。 对于那些写代码用英文,写注释用英文,平时也不用处理非英文数据的人来说,转3的动力的确不强。 我的看法是, * 1. 如果你手上已经有2的项目要维护,那就继续用2,不要做迁移。 * 2. 如果你要新做一个web项目,先去看看cherrypy能不能满足你的要求。如果可以的话,就用3,不行就用2 * 3. 如果你已经知道你要做什么,先去找找相关的库对3是否支持,如果不行,就用2 * 4. 其它情况,能用3就用3 总的来说就是能用3就用3,毕竟3是未来的方向,而且的确有相当一些细节上的改进 但如果不能用3的情况下,那就用2,不要勉强。 === ubunoon === {{{ ubunoon netubu# gmail.com 发件人当地时间: 发送时间 15:43 (GMT+08:00)。发送地当前时间:下午5:07。 ✆ }}} * 1、大部分使用的是CPython,运行速度与其他编译型语言相比,还是不够快速 * 2、万恶的GIL * 3、嵌入到C比较麻烦。 * 4、框架太多 * 5、资料还是相对较少 * 6、IDE,很难找出一款好的IDE,来一统Python的天下(或者是桌面或者是web开发) * 7、商业应用支持还是比较少 (这个才是重点) * 8、google复杂问题的解决(就好像之前我发的PySide的问题),还是不够给力。 === CJ === {{{ CJ jamchange# gmail.com 发件人当地时间: 发送时间 16:57 (GMT-08:00)。发送地当前时间:上午1:08。 ✆ }}} * Python的Object & Class 系统有逻辑上的问题 * 1. Object支持了__eq__方法,为什么还要实现__ne__方法?很基本的哲学道理,一个可推导的世界中,A==B为真,则A!=B一定为 假,__ne__方法大家都不会用,那就应该人Python中去掉,免得引起混乱 * ~ HYRY ^发送时间 07:16 (GMT-08:00)。发送地当前时间:下午5:08。 ✆^ * 有时候写 `__eq__,__ne__`方法不是为了比较,而是为了生成别的代码,例如SQL。我最近正好写了一个编译器,它需要在某些条件下在 `__eq__,__ne__`中抛出不同的异常。如果没有`__ne__`那就麻烦了。 * 2. classobj与type这两个东西确实该去掉一个,鸡乎?蛋乎?(Python 3去掉了classobj) * Python的字符串unicode,寄期望于Python 3 * Python的lambda只支持表达式,Python仍然区分表达式与语句,这点导致lambda里没了if(虽然你也可以找很多其它的理由来解释 lambda里的代码不应写得复杂),还有Python的closure * Python函数的tail_call_optimize * "".join 你懂的,Python有些库的方法命名有些奇怪,有些有下划线,有些没有下划线。有些类是全小写,有些类是Camel,Java这些方 面就很好。。。。历史遗留问题啊 * Python的文档????我看django文档时,只想着一句话:Read The Fucking Source Code!!!有些函数的文档我看半天还是没搞清楚倒底怎么个用法,一是函数参数没有类型说明,另一方面,我还是比较喜欢直接的example。(感觉Java的API文档也要比 Python的好很多喔,整洁不少)。 {{{ Leo Jay python.leojay # gmail.com 发件人当地时间: 发送时间 17:19 (GMT+08:00)。发送地当前时间:上午9:10。 ✆ }}} 说到这个我想起来,python的文档很SB的地方是,它很少说一个方法调用是否会抛异常以及抛什么类型的异常。 * 比方说int这个函数,它就说了句:如果转入参数不是字符串,会抛TypeError,然后就没了。要是你因此你只抓TypeError的话就傻了,因为如果字符串不是数字的话,抛的是ValueError。 * 如果因此,你写try ... except代码都写成 {{{#!python try: foo() except: ... }}} * 的话,你也可能中招,因为sys.exit()的退出方式就是抛一个异常。如果你foo()有逻辑在一定情况下调用sys.exit来退出的话,你会发现这个异常被你抓掉了。。。 所以我现在养成习惯,代码都写成: {{{#!python try: foo() except Exception: ... }}} 而更多的方法,比如time.sleep,文档压根就不告诉你,它可能会抛异常。 `总之,越来越多的“懂OO的java工程师“进入python领域,导致python越来越差劲` * 不要老是这样说吧,不能因噎废食,我看GTK库的C语言接口时,发现实例方法在C中的实现无非是将this struct一致作为函数第一个参数而已。 * 你要是在Python中,明明可以写成socket.read(length)的,非要写成read(socket,length),然后方法名又会冲突,又要写成socket_read(socket,length)或是socketlib.read(socket,length),不成了胡折腾了吗,呵呵 * 我想起了程序员A,发现Event、Observer很好用很灵活(那个面向事件面向消息编程嘛),就所有的调用都bindEvent再那个triggerEvent,明明只需要一个callback就解决了,非说Event更灵活更具可扩展性就像那些刚看了些OO设计模式的,就在10行代码内用了20种设计模式,这就是那些"懂OO的Java程序员"干的事 * 然后另一个程序员B,看了些Lisp,然后就一个劲的在python中lambda map reduce filter ,明明用Class,用对象实例来表示更方便的,非要把变量放到closure中,然后就像个黑盒子一样调方法。。。。然后这些程序员还喜欢不用if else,非要用andor什么的。悲催啊 Python中的OO和lambda确实实现的不咱地,有谁能解释下`__new__与__init__`的功能?? 这方面Ruby又是一个好的学习对象,Ruby比Java更OO,但更具有一致性,比如new也是一个方法(Ruby中的说法是向对象发送一个new的消息,又是面向消息嘛,呵呵) * 我喜欢Ruby的一个原因是它其实像Lisp+Smalltalk。说起来,论OO特性,Python没地位,论FP特性,Python也没地位,论标准库,Python的工具库很多,但标准库似乎有些Out。剩下的只有Python语法简单了,但Python还有神马的元编程,多继承,我我我。。。 所以用Python,即不要太OO,也不要太FP,因为它在这两方面都不擅长(我只说不要太OO,太FP,不是说不要OO,不要FP哦,呵呵)。也不要指望Python运行速度多快,在这方面我已经开始使用Go语言了。 `Keep it simple`,才是Python之禅!^O^ === 依云 :中文问题! === {{{ lilydjwg # gmail.com 发件人当地时间: 发送时间 17:20 (GMT+08:00)。发送地当前时间:上午9:11。 ✆ }}} On Wed, Dec 21, 2011 at 04:05:19PM +0800, 智障 wrote: > 俺觉得俺现在用着Python2也挺好,编码问题不是什么大问题加#-*- coding:utf-8 -*-用章鱼编辑器的自动插入功能,也挺方便。 如果你认为所谓的「编码问题」指的是这个的话你就大错特错了。Python 2 在引 入 Unicode 后即混淆了 str 和 unicode——在一个需要字符串的 API,你既可以传 str 也可以传 unicode。有些 API 没处理好,如: {{{ >>> os.path.join('中文', u'路径') Traceback (most recent call last): File "", line 1, in File "/usr/lib/python2.7/posixpath.py", line 71, in join path += '/' + b UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128) }}} 经常会遇到这种情况。然后你 encode 或者 decode 一下就解决了。问题是,这种 问题没有规律。 还有一个问题是, {{{ >>> '中文' '\xe4\xb8\xad\xe6\x96\x87' >>> u'中文' u'\u4e2d\u6587' }}} repr 的结果不可读。这意味你 print 一个 list 或者 dict 什么的,你看不到其 中的中文。 ==== pansz 指正 ==== {{{ pan.shizhu # gmail.com 发件人当地时间: 发送时间 08:24 (GMT+08:00)。发送地当前时间:上午9:13。 ✆ }}} * 其实不存在混淆 str 跟 unicode 的问题,需要 str 的地方会自动把 unicode 转成 str,需要 unicode 的地方会自动把 str 转成 unicode。 * 问题在于缺省的转换使用的 ascii 编码,因此只要含有中文的,一律不能通过 python2 的"自动类型转换"。 * 所以编程过程中凡是存在这种"自动类型转换"的环节,一律需要改成手动转换。----我以为只要理解这个,几乎可以解决python2 90%以上的编码问题。 * `repr 的结果不可读` ... 这个问题产生的原因跟上述是一样的,py2 缺省输出ascii ,不是 utf-8 。。。因而自然不能看到。 * 但是如果你只是要 print 的话,一个非常非常简单的办法是:`输出为 json,并指定为 utf-8 格式`,json编码器增加 default 函数为 repr(obj)。这样的输出几乎跟 repr 完全一致,除了那些乱码中文变成了真正的 utf-8 中文。 其实说了那么多, py3 对国人唯一的重要改进仅仅是"缺省编码由 ascii 修改为了utf-8"而已。 * 为了这点点改变去伤筋动骨的大修整个语言,并且弄得向后不兼容。有点太过了。简单的修改一下 python2 源代码就能做到的事。。。 === zhao shichen === {{{ shichen.zhao# gmail.com 发件人当地时间: 发送时间 18:10 (GMT+08:00)。发送地当前时间:下午6:54。 ✆ }}} * 1.很多标准库很烂;而很多很好的库竟然不在标准库之中,比如chardet等等,而xml之类没用的东西反而有 * 2.lambda演算太弱:如果有类似(x,y)->这样的语法就更好了;python3竟然进一步的削弱了lambda演算的能力 * 3.字符串的join看起来太奇怪了 * 4.发展了自己的一套正则表达式,直接用pcre不好吗。而且这个库的使用我感觉不友好。 * 5.听说python的unix域socket的性能不佳,仅仅是听说,在我的简单测试中感觉unix域socket的速度和普通socket速度一样:应该快一倍才对。 * 6.没有标准的IPC函数,比如共享内存,消息队列等,这些东西很有用阿 * 7.引入了太多java里面的垃圾概念,就是那些面向对象的东西。导致本来很简单的东西搞得很复杂,最典型的例子是logging模块,这个模块太烂了 * 8.socke的函数支持不全,比如sendfile等等都没有支持 * 9.很不喜欢元类编程,把本来很简单的东西搞复杂,都是java里面的垃圾概念 在我的项目组中,基本上不准编写类,只允许编写函数,目的就是为了方便集成和控制代码; 象很多java项目比如eclipse一样搞得又大又臭是绝对没法接受的 `总之,越来越多的“懂OO的java工程师“进入python领域,导致python越来越差劲` === shhgs === {{{ shhgs.efhilt # gmail.com 发件人当地时间: 发送时间 18:56 (GMT-05:00)。发送地当前时间:下午8:06。 ✆ }}} 问题还是很多的 * 1. 匿名函数。Py3一度要取消lambda,脑残了不是。正确的做法应该是进一步加强lambda,搞匿名函数 * 2. 莫名其妙的local域。我写twisted的时候,没少吃药。稍微不留神就掉坑里。 * 3. 很多类库的port都不完整。socket,readline,ncurse 。。。 * 4. 为什么要区分表达式和语句?有这个必要吗?表达式全部返回None,或者专门定义一个Void岂不是更好? * 5. Py的标准类库应该修订一下了。标准类库的质量良莠不齐,有些类库明显落伍。htmllib, * sgmllib ,HTMLParser,现在还有人用吗,为什么不用lxml?re,建议用pcre;ConfigParser,建议去掉。 * 6. 进一步增强easy_intall。应该设计类似rpm, dpkg这样的Python library package。以类似yum,apt的方式分发这种包。 === Shell Xu === {{{ shell909090 # gmail.com 发件人当地时间: 发送时间 22:06 (GMT+08:00)。发送地当前时间:上午9:01。 ✆ }}} python的整个系统,我其实有非常多的不满。但是用任何一门语言都是取舍问题,如果有一门语言,库够多,已读,易用,性能高,我毫不犹豫立刻转过去。python的强处在于庞大的库,还有非常好的易读和易用性。 * 但是相比来说,性能一直是个问题。python的实现性能大约和C相差五倍上下。如果是大规模计算问题,大约能差10倍以上。当然,我们可以写C扩展,但是这就不是使用python了。我们也可以说,很多时候我们不需要这么快的速度。这是个事实,但是不改变python性能差的事实。python不但性能差,还有GIL这个玩意。以至于我现在对高并发计算都采取多进程的模式。多进程模式的通讯效率肯定比多进程低,而且麻烦。 * 另外,python在底层设计上,也表现出很强的实用主义倾向。这是比较外交术语的词汇,更加直白的说法应当是,混乱,不知所谓。在闭包设计上采用free variable设计,而不是lisp中的environs设计。区别? * 你试试看在外层闭包中 `from lib import *`。由于引入不定个数名称,free variable无法处理。类似的问题还有LEGB规则,新手往往要花很长时间研究这个例子究竟是怎么错的: {{{ #!python a = 1 def f(): print a a = 2 }}} * 我勒个去,这种反直观反人类的事情都有,还敢说自己易读。 * 还有坑爹的元编程,这东西根本是坑爹中的坑爹货。如果你用过多重继承,大概就知道python的整个OO系统看起来根本是大型的仿真,到处都是乱糟糟的。C++怎么解决多重继承的?你最好别用(真心说,这可比python更加坑爹)。java怎么解决多重继承的,只能继承Interface。其实这是变相的变成了Interface-Impalement模式。python怎么解决的?MRO!为什麽一个类加个__metaclass__就会改变性质啊,为什麽一个类去生成另一个类的写法是----我基本不记得了,反正web.py里面有用到,需要的话去炒栗子吧。为什麽方法要隐藏居然要改名字加__啊。你到底是在做OO还是在看起来像OO的东西上狂打补丁啊魂淡。 * lambda表达式弱智。我和人讨论过,lambda是否是图灵完备的。结论还是完备的,不过需要借助Y combinator。何必呢?由于强调lambda的快速特性,因此将lambda强制在一行以内(没有结束标记),导致python其实是没有匿名函数的。一个callback数组写的难过死。 * 语法糖太多了点,当然,这是纯粹的个人感觉。语法糖是把双刃剑,用的好,可以简化编写和阅读,但是太多,往往容易引入语法混乱和额外的约束。 * 另外,语言的自构建特性混乱。虽说不是每门语言都强调自构建特性,但是通常而言,都是使用C实现一个内核,由内核实现一些基础操作。再由基础操作实现更复杂的操作。每层的边界都是比较清晰的。谁来告诉我,python中有多少库在移植时是由纯python实现的?库的相互依赖层级是? * python的沙盒化也是个问题,如果沙盒做的够好,我完全可以把python作为一个客户级别的平台。用C写一个很简单的类似浏览器的东西,下载一个URL的python包回去运行(或者仅仅检查更新)。从而保证本地效果/跨平台/安全性。现在?一个都保证不了。我连把一个python包转移到另一台同构设备上都很麻烦(如果两者不是严格匹配,例如系统差异,系统版本差异)无论是web开发还是移动终端开发都必须走传统模式。 === 赖勇浩 === {{{ mail # laiyonghao.com 通过“googlegroups.com” 发件人当地时间: 发送时间 22:31 (GMT+08:00)。发送地当前时间:上午9:04。 ✆ }}} 个人看法:支持 native thread 是它最大的错误。 === pansz === {{{ pan.shizhu # gmail.com 发件人当地时间: 发送时间 08:35 (GMT+08:00)。发送地当前时间:上午9:15。 ✆ }}} 我觉得这些是缺点: * 1。python3 的存在,python2 如果没缺点 python3 就不需要存在了,源代码还不兼容。这会造成不小的混乱。 * 2。没有一个堪比 Java 性能的 JIT 实时编译解释器。 * 3。源代码无法真正意义上的加密(当然解释执行类语言都有这个问题,Java 也一样,反编译太容易。。。而象 C++ 编译之后基本不可能反出源代码。) Python 目前为止主要用于服务器端,正因为解释型语言都不可能真正意义上的加密源代码,所以只有部署在服务器端能避免这个问题。 == 对于 pypy == Leo Jay python.leojay# gmail.com 发件人当地时间: 发送时间 15:12 (GMT+08:00)。发送地当前时间:下午5:05。 ✆ 回复: python-cn@googlegroups.com * ~zw g pekingmaster# gmail.com * 大家对Py3都是一边倒说好呀。但是,有牛人好像对Py3很有意见呢,这又怎么说? * http://lucumr.pocoo.org/2011/12/7/thoughts-on-python3/ * ~ Leo Jay python.leojay# gmail.com * 我看还早着呢。对CPython的第三方库支持不好是硬伤。pypy之于python就像mono之于.net,openjdk之于java,大家都说他们好,但都叫好不叫座,真正用的时候,你总是时不时会发现有那么一些地方跟原版兼容性有问题 ##endInc ---- '''反馈''' 创建 by -- ZoomQuiet [<>]