##language:zh #pragma section-numbers off ##含有章节索引导航的 ZPyUG 文章通用模板 <> ## 默许导航,请保留 <> = 类似Python这种动态语言的一个疑惑 = [[http://groups.google.com/group/python-cn/browse_thread/thread/c93dc5bf38052c0b/c4612e3db3d55467#c4612e3db3d55467|类似Python这种动态语言的一个疑惑]] * ZoomQuiet 按: 这是一个经典的学院派开发者进入Pythonic 世界的硬科幻级疑问... ##startInc == 初问 == {{{ Zhang Jiawei 发件人当地时间 发送时间 11:33 (GMT+08:00)。发送地当前时间:上午9:56。 ✆ 回复 python-cn@googlegroups.com 发送至 python-cn 日期 2010年12月25日 上午11:33 主题 [CPyUG] 类似Python这种动态语言的一个疑惑 }}} codebase 中 merge 了别人的代码以后。即便双方都没有改动同一个文件,也可能出现这种情况: * A 只改动了 a.py 的一个方法的传参个数。 * B 改动了 b.py, 并且 b.py 中调用了 a.py 中的那个方法改动前的版本。 merge 了两个文件以后, 程序员基本都不会意识到现在出了问题。 原因有两个: 1. python 程序员基本不用什么IDE, 如果使用 pydev 之类, 大致还能依靠 IDE 在merge 以后看到这个错。 1. python 没有编译的概念,没有机会看到编译器对这个语法问题的报错。 好了,现在只有等上线以后,通过某个事件触发这个bug了。 请问各位是杂么防范这种问题的? unit test ? == 强答 == {{{ 沈崴 日期 2010年12月28日 上午10:58 主题 [CPyUG] Re: 类似Python这种动态语言的一个疑惑 }}} On 12月25日, 上午3时33分, Zhang Jiawei wrote: 关于这个问题, * 首先,我并不认为这是一个真正的 bug。真正的 bug 是改动了 b.py 中接口的逻辑和用途,但是接口名和参数个数并没有变化。这种在编译语言中完全正常的,恰恰才是真正最为危险的情况。 * 而在讨论中,大家都在想办法保证参数个数必须一致的问题,我这里随便举个例子:{{{ adduser(username, passwod) adduser(name, gender) }}} * 作为同名接口,都具有两个参数,甚至都是字符串类型的,而且无论在编译还是运行期都不会报错。似乎符合 “没有出错”这个判断 bug 的标准,但是,这会产生极为严重的问题 —— '''真正的逻辑错误'''。 所以我想说的是: {{{ 试图使用静态检查,和使用 IDE 进行参数约束的想法,才是真正危险的! }}} * 需要明白,报错和 core dump 并不是真正的 bug,也不是敌人。 * 要写出真正安全,减少 bug 的好程序,就要反过来做,不仅要允许参数不一致,而且还要'''尽量制造这种错误'''。 * 除了在 python 和编译语言中都有的 assert 方法,python 提供了更多可以避免这种情况发生的机制。比如显式参数名调用: {{{#!python def adduser(**args): u = args['username'] p = args['password'] #... }}} 如果这样调用 adduser(name='tom', gender='male') 就会出错,这时调用者 可以立即明白,逻辑上有问题了。你的程序就真正减少了一个 bug。 * 关于 python 中这些安全机制,我在一些场合已经讲过很多,大家可以补充。 所以,结论完全相反,比起静态语言,像 python 这种动态语言更难产生 `"bug"`。 * 使用 IDE 对于避免 bug 有一定优势也有劣势。至少 python 不会比静态语言更危险。 > 1. python 程序员基本不用什么IDE, 如果使用 pydev 之类, 大致还能依靠 IDE 在merge 以后看到这个错。 * ~ 当然我无论写 python,c\c++ 还是 java 之类都不会用 IDE,其实在你公司之外 许多人都是这样的。 > 2. python 没有编译的概念,没有机会看到编译器对这个语法问题的报错。 * 关于编译的问题,这里先不谈 .pyc .pyo。其实每个 .py 文件都像一个 .so / .dll 文件。如果静态语言这么搞,上面提到的这种小问题一样多,之所以静态语言看似没有这种问题,很大原因是因为它这么搞太麻烦了。 * 当然很多人对''把静态语言搞成一种动态语言的这件牛逼的事情''乐此不疲。 * 静态语言的项目,除去真的全部都是静态链接起来,的这种情况。一样会遇到你提到的困扰。 * '''所以,这本身就不是一个动态语言的问题。''' > 好了,现在只有等上线以后,通过某个事件触发这个bug了。 我想说的是: {{{ 即便上线了,当有问题时不出错,才是真正可怕的事情。 }}} 上线的程序,都需要从静态语言崩溃和动态语言报错中恢复的机制,和错误报告机制。 当然,当程序上线时,traceback 总比 core dump 要可爱得多。 而且动态语言调试又要方便一些,用户很快可以得到更新补丁。 * 所以结论又是相反的,上线以后,动态语言情绪要稳定得多。 > 请问各位是杂么防范这种问题的? > > unit test ? 所以结论是,'''不仅不防范,而且还要尽量制造和纵容这种所谓的错误。''' == 继续 == On 12月28日, 上午4时59分, Wei guangjing wrote: {{{ > 在 2010年12月28日 上午10:58,沈崴 写道: > > 而在讨论中,大家都在想办法保证参数个数必须一致的问题,我这里随便举个例子: > > adduser(username, passwod) > > adduser(name, gender) > > 作为同名接口,都具有两个参数,甚至都是字符串类型的,而且无论在编译还是运行期 > > 都不会报错。 > > 静态语言是不会有这个问题的,因为不可能定义2个同名并有同样参数个数的方法。 }}} 两个同名并有同样参数个数的方法 ---- c++ 可以 python 不行。 * ~沈崴 * 我的意思是,B 在项目里负责共享库 libB.so (相对于 b.py),里面实现了{{{ adduser(username, passwd) }}} * 明天 B 把 libB.so 中这个接口改成了{{{ adduser(name, gender) 或者 adduser(name, gender, age) }}} 的情况 ;) === 矫枉过正 === {{{ Zhang Jiawei 发件人当地时间 发送时间 20:38 (GMT+08:00)。发送地当前时间:上午10:03。 ✆ 回复 python-cn@googlegroups.com 发送至 python-cn@googlegroups.com 日期 2010年12月28日 下午8:38 主题 Re: [CPyUG] Re: 类似Python这种动态语言的一个疑惑 }}} 如果得出这样的结论,我感觉有些矫枉过正了。 1. 真的是个bug, 因为用户访问到这个语句行的时候,报错了。 1. 我们不可能要求无论谁在写参数列表的时候都用map。 1. 我的案例实际上用IDE或者其他的静态检查机制其实就可以解决问题,而且安全省力,没有附加步骤。 1. 您说的参数语义的内涵发生变化而导致的问题其实开辟了第二个案例。其实静态语言里也存在,用 map也解决不了。因为大家merge代码的时候仍旧没有人意识到这里有问题,只有调用的时候才会发现问题。靠 unit test 应该能检查出来。如果unit test没报错,那么错的也是对的。 1. IDE 或者 静态检查 的确检查不出您开辟的第二案例,但不等于 IDE 或者静态编译就是危险的,他们在自己力所能及的范围内检测出某些问题即可。比如我的案例。 1. 我还是觉得不用把事情扯到静态语言的动态链接上,事情很简单,适用范围没有那么大,就说两个py之间 和 两个 .c 之间都有互相调用,如果 .c 是静态编译,通过编译器的报错会比执行到py才报错安全的多。即便是动态链接,楼上的朋友说了,参数个数的变化至少是可以通过编译发现的,因为.h 变了。您的第二案例,无论是动态语言还是静态语言都没办法不通过Unit Test解决。 1. 我的案例同样是上线了,有问题不出错,和您的案例一样可怕。我和您的案例同样在静悄悄的等待出错的机会。 所以我想说的是: 1. 试图使用IDE和静态检查机制解决所有问题是危险的,但是进行参数约束还是安全的,起码参数的个数首先没问题,然后再用Unit Test去保证参数语义的准确。 我的结论依旧,'''动态语言的出错几率会比静态语言大'''。靠 `静态检查 + Unit Test` 双保险解决问题。除此以外自己给自己制造问题太折腾。 另:c/python 好说,我想像不出 java 不用 IDE还能用什么写? ==== 吐糟 ==== {{{ Zoom.Quiet 发件人当地时间 发送时间 10:32 (GMT+08:00)。发送地当前时间:下午11:09。 ✆ 主题 Re: [CPyUG] Re: 类似Python这种动态语言的一个疑惑 }}} 嗯嗯嗯,其实呢,俺是理解 沈论的,只是没有他那么多案例来支撑; 内什么,,,其实呢,大家心里想说的和 Jiawei 在反馈的问题,完全不是一个位面的事儿! 不论是 蟒禅还是蟒之8荣8耻,一直在表达的都不是语言的什么动态性,这些都是浮云! * 真正一直在吼的是:{{{ - 只有人才靠谱!工具都TMD 没谱! - 只有想明白的人才可能写出明白的代码,IDE都TMD的是忽悠! - 只有工程才是问题,技术从来都是有解决途径的! }}} 不论Python/Erlang/Perl 等等广泛得到程序使用但是从来没在主流商业领域得到青睐的开发语言, 都有独特的开发文化包含在其中,涉及到动态语言的开发, 近年 erl 的兴起,其内置的质量保证方式之一就是"脆崩"或是说"速死"~进程只要有一点儿不对味立即死亡,绝对不允许继续呆在内存中影响其它进程!这样才能确保整个系统是稳定的... * 用Python 来进行团队協作时,也一样,妄想通过工具来确保基础的神马参数统一/接口统一/运行期统一,那是自虐! Python 赋予了程序员极大的自由度的同时,其实就是在纵容和放大了这类人为逻辑错误的危害!从而促使团队开始思考如何才能真正的协同起来,而不是象JAVA 一样,形成用华丽/复杂/坚固的类树进行安全隔离的一堆码农! > 0. 真的是个bug, 因为用户访问到这个语句行的时候,报错了。 - 写出这种代码来的人,才是bug > 1. 我们不可能要求无论谁在写参数列表的时候都用map。 - 为什么呢? 一个团队难道没有任何统一规约的嘛? > 2. 我的案例实际上用IDE或者其他的静态检查机制其实就可以解决问题,而且安全省力,没有附加步骤。 - 也就是说,不期望成员真正明白什么是逻辑错误了? 那么人的创造力是无限的,总是会有人写出NB到IDE也检查不出的隐藏逻辑 bug 的,每年 C++/JAJA/C# 制造了无数神奇的这种bug,在 Python 中,难道还要在 IDE 养护中促进这种 bug 的创造!? > 3. 您说的参数语义的内涵发生变化而导致的问题其实开辟了第二个案例。其实静态语言里也存在,用 map > 也解决不了。因为大家merge代码的时候仍旧没有人意识到这里有问题,只有调用的时候才会发现问题。靠 unit test > 应该能检查出来。如果unit test没报错,那么错的也是对的。 - unit test 也是人写的,也有工作量的,如果良好的团队规约,交叉审阅等等促进团队知识管理的柔性协同可以从根儿上解决问题,为什么要使用同样包含问题的测试代码来解决问题代码? > 4. IDE 或者 静态检查 的确检查不出您开辟的第二案例,但不等于 IDE 或者静态编译 > 就是危险的,他们在自己力所能及的范围内检测出某些问题即可。比如我的案例。 - 他们是谁? 是IDE 的团队,不是你的团队,想通过这种方式来提升自个儿团队的生产力是种美好的想象... > 5. 我还是觉得不用把事情扯到静态语言的动态链接上,事情很简单,适用范围没有那么大,就说两个py之间 和 两个 .c 之间都有互相调用, > 如果 .c 是静态编译,通过编译器的报错会比执行到py才报错安全的多。即便是动态链接,楼上的朋友说了,参数个数的变化至少是可以通过编译发现的,因为 > .h 变了。您的第二案例,无论是动态语言还是静态语言都没办法不通过Unit Test解决。 > 6. 我的案例同样是上线了,有问题不出错,和您的案例一样可怕。我和您的案例同样在静悄悄的等待出错的机会。 > - 所以,沈游侠强调的是,应该想办法让这种问题在上线前就暴发出来哪,,, > 所以我想说的是,试图使用IDE和静态检查机制解决所有问题是危险的,但是进行参数约束还是安全的,起码参数的个数首先没问题,然后再用Unit > Test去保证参数语义的准确。 > * 呃,,,所以,写JAVA 代码就象打字员,除了忍受越来越长的参数之外没有任何办法(所以IDE很依赖 ;-) * 所以,Py/Ruby/Lisp ... 都为程序员的生命着想给出很多减少输入的参数声明方法 * 但是,要成功偷懒得整个团队一起来,否则最后全部倒霉 ... > 我的结论依旧,动态语言的出错几率会比静态语言大。靠 静态检查 + Unit Test 双保险解决问题。除此以外自己给自己制造问题太折腾。 > 这个结论和大家没有什么不同哪,只是解决态度有不同 * 容易出错是个福利,而不是 bug * 每一错误,都导向更加高效/靠谱/简洁的代码书写 * 依赖 静态检查和测试案例,则导向更多的隐藏错误 === Exoweb === {{{ jiakeke@gmail.com 发件人当地时间 发送时间 19:16 (GMT+08:00)。发送地当前时间:下午10:29。 ✆ 主题 Re: [CPyUG] 类似Python这种动态语言的一个疑惑 }}} 我说说我原来在Exoweb时,我们的项目是怎么处理你这个问题的吧。 * 首先一个任务在被程序员选择,编写并提交后,无论修改或者添加了任何的功能一定要写至少一个的 test 来保证所修改或者添加的功能的正确性,所以绝大部分的类似的问题在这一层次就可以被堵住了。 * 然后如果有问题突破了test 这一层,那么接下来,任何的一个提交都要由项目组里面的全部或者绝大部分的成员做过 code review 并且没有任何问题后才可以被作为候选的更新等待负责项目更新的人来合并到生产环境中去,这里 team leader 要负绝大部分的责任,一但后续发现某一个提交有问题,那么会直接找team leader 来负责的,当然此处不存在打击报复,但是仍然会被列为此team leader本人的绩效考核中去的。这个项目组内部的code review非常细致,可以细致到某个逗号后面是否应该有一个空格的地步。 * 再次,即便有类似的问题真的突破了项目组的范畴,每一个负责向生产环境更新的负责人,对于所有的要更新到生产环境的代码也要重新进行review,以确保不放过任何一个错误,这里我要说的是,每一个做这个事情的人,都是非常熟悉整个系统的,并且非常的认真负责的,并且这样的工作也是包含在绩效考核中的。 * 最后,谁也不能保证生产环境没有任何的bug,如果出现了bug,简单的可以就地,hot patch,然后给代码库增加一个补丁,复杂的bug那就直接回滚到之前的版本,等修复之后再次更新。一般这样的线上处理也都很快就成处理完。 以上这几个步骤应该能够防范你所遇到的问题了吧? * 这些步骤实际运行了有几年了一直很顺畅,不过这些是我07年离开Exoweb之前的事了,经过了这3年肯定又有所改变了,不过我想大体上应该还差不多吧,如果有路过的现在在Exoweb的人可以就我所说的不足或者错误或者现在又有什么新的流程再做一下补充吧。 * 补充一点,在我离开的时候,99%的开发人员都用 vim或者emacs 没有任何的IDE存在,整个公司除了财务大姐其余所有人都用Linux 或者 Mac。 {{{ Gary Jia http://www.jiake.org 珍爱生命,远离京东! http://www.tianya.cn/publicforum/content/free/1/1662804.shtml }}} * ~ ZoomQuiet :补充背景,Exoweb 就是 python.cn 域名所有者,也是 CPyUG 列表的前身 python-chinese@lists.python.cn 列表的发起者,是家面向北欧企业的软件服务厂商,最早在中国使用 Django 进行商用系统开发的外资公司; 企业文化很敏捷, 可以参考以前的会课记录: http://wiki.woodpecker.org.cn/moin/BPUG/2006-08-27 === 人肉味太重 === {{{ Zhang Jiawei 发件人当地时间 发送时间 21:10 (GMT+08:00)。发送地当前时间:下午10:46。 ✆ 主题 Re: [CPyUG] 类似Python这种动态语言的一个疑惑 }}} 做的确实非常好。 我也补充几点: 1. 这样环境并非哪里都有。 1. 你们的流程非常好,但是仅仅从描述我都感受到了巨大的人肉成本,所以我们从来都在说一个意思,但是我更倾向于简单的问题能用工具就用工具去提早发现,复杂的问题才需要人肉介入。 * 没有IDE存在我个人并不感到敬畏,因为只不过是适用场合的问题。如果你说写Java你不用IDE,我的确会感到敬畏,而且十分想了解你们是杂么做的,我还特此发了个邮件给沈大,结果得到的答复不过是戏謔之词。我本人的Vim技巧大抵不会比你们公司里任何人差,相信还比大多数人好, * 我在公司内部的例会上还做过专门的Vim演示去推广,发过邮件给Vim的作者提示他的Vim主页上没有加上他名字的中文版本,并且得到了该作者的答复和更正。我从来不正面刻意的去宣扬非IDE的意义,相反我在某些场合推荐IDE的存在,尤其是在Python的领域,这不代表我不知道Vim/Emacs系的好处,而是我更深知选择他们的场合。我研究过python.vim的源码说实话,真的够烂的。我也研究过pydev的eclipse plugin, 说实话,真的很用心的在写。 * 如果你们是做Python Web的,我认为不使用IDE大致问题不是那么大,因为在一个稳定的web framework之下,需要掌握的api就那么几个,从一个request过来到一个response返回就这点破事,比较费劲的是业务逻辑,完全是用基础的Python语法就可以应付。 * 如果你们是写PyQt一类,对不起,用Vim之类是自虐。因为那是C++的原生接口,Python 只是胶水语言,大妈扯到 Python 接口可以减少参数输入,在这里是不适用的。尤其面对成千上百个 GUI API 每个API有诺干个参数,每种参数的输入有各自的界面效果,再加上各个API之间的叠加效果。好吧,还是郑重推荐 PyDev。还是那句话,看场合,分情况来解决问题。 * 最大的问题就在这里,用 Python 和 用 Vim/Emacs 一样,并不显得你比别人高一等。说话做人都不要那么偏激,不用把其它诸如 Java, IDE, 静态检查都说的一文不值,相反我印象里 Pythoner 更应该低调才是,两个字概括 '''“暗爽”'''。 * 你们有一个除了大姐都在用Linux或者Mac的环境,很好没问题。我在一个几百人都用Windows的IT公司里,应该比贵公司的市值要高很多很多倍。一个人一点一点的给自己开发机上的Ubuntu配置了能运行公司代码的工作环境 -- 我的桌面永远都是紫红色的。 === 人,还是人! === {{{ jiakeke@gmail.com 发件人当地时间 发送时间 22:21 (GMT+08:00)。发送地当前时间:下午10:49。 ✆ 主题 Re: [CPyUG] 类似Python这种动态语言的一个疑惑 }}} 环境无非是由人组成的,只要有足够多的靠谱的人什么环境都可以有。 * 这样简单的问题只要看一眼代码就可以发现吧,如果这么简单的问题都需要依赖工具来帮忙发现,那怎么能相信他可以发现复杂的问题? * 用不用IDE全凭个人爱好,不用IDE完全不需要被敬畏,没有写过Java,不过既然提供了命令行的编译工具,应该也有办法不用IDE吧,不过仍然看个人爱好。 * Python写了很多年,用过 zope/plone, twisted, django, 没用过PyQT,但是写了不少wxPython的东西, 一直用vim来写程序, 不会用emacs,vim对于我来说就是一个用的顺手的编辑器而已,估计你的vim用的比我好,我既没有研究过vim的源码,也没有跟vim的作者通过信。pydev没有用过,但是看过别人用,好像时不时的会弹出一个提示框,估计关来关去的应该挺烦人的吧,不过既然你这么喜欢可能会直接购买那就没有这个问题了。可能没有写过PyQT吧所以没有体会过你所说的用vim写Python如何的自虐。 * 从来没有觉得用Python或者vim比别人高一等,无非混口饭吃,暗地里也没有觉得有什么爽的。 * 我离开Exoweb的时候只有50个左右人,现在3年过去了,应该也不超过100人,市值肯定没有你们几百人的公司高,几百人光买Windows的license 得多少钱啊,别说还得买杀毒的杀什么的了,我们可是小公司,真买不起啊。 * 你能一点一点的给自己配置Ubuntu比我强多了,我很懒所以用Mac,我的桌面是我闺女的照片。我们原来的财务大姐非常的让我敬畏,她居然连税控机,税控软件都弄的明白,太不可思议了,我真不成。 ##endInc ---- '''反馈''' 创建 by -- ZoomQuiet [<>]