1、从python看编程语言看对我们工作的影响刘喆16页精选文档Part 1 刘喆: 首先感谢大家在周末来听我讲这个东西。刚才大家听上一次讲了Python应用感觉怎么样?我形容一下,Python这个东西太好了,我一定要学,还有的说我正在用,我终于选择了一个好的东西。下面我给大家泼点冷水。 我演讲的主题是从Python看编程语言对我们工作的影响。为什么选这么一个主题呢?因为我们这次基调是讲Python,但是我本人不是一个Python很精通的人。后面我会给大家讲为什么。因为我经常用的像java,还有各种乱七八糟的语言,可能大家没听说过的。所以我就讲编程语言对我们工作的影响,其中以Python作为例子。
2、 先讲一下Python哲学。我以前的老大教会我一句话,教“你要学一个什么东西,用生命周期法,想了解一个人,先了解他以前干过什么,了解一个语言先了解它是什么样的”。讲讲Python哲学,有人研究过这个东西吗?看来没有。 在1989年的时候Python诞生,怎么诞生的呢?这个作者他要写一个很简单的语言,从ABC语言里面抽取了一些他想要的特性,从MOUDULE-3抽取了一些东西,从SHELL里抽取一些东西,就有了Python。他一开始的设计是反Perl,看看有没有人了解TMTOWTDI?这个东西是Perl哲学,你做事情有很多种方法,Python之初就是反这个东西,你要做一个事情应该尽量用比较少的方法
3、,为什么?比如两个人交流,像我们中国,地大物博,有很多的方言,最严重的是在闽南地区,我以前有两个同学都是福建人,他们俩家离的很近,他们两人说的话互相听不懂,方言现象很严重。所以当时非常流行的Perl就有这样的问题,同样一件事情写的代码完全看不懂,Python的作者说我们不要搞这么复杂,我们讲普通话吧,所以他就是反Perl哲学。第三个,它是多范式的,以前我不懂范式,在我上大学的时候图书馆充斥着各种书叫什么什么范式,我当时觉得好高大上,不知道这是什么东西,我去图书馆把所有讲范式的书看了个遍,其实没有什么,大家都在讲怎么样面向函数。讲深一点的会讲模板怎么用的,范式是想告诉你我们写程序可能是这样一种方
4、法,也可能是那样一种方法,而Python是多范式的,你可以面向函数,你也可以完全不管它,这一点比较自由。 还有一个比较重要的是字符串处理,曾经我们工作中很多地方会用到,尤其是互联网,HTML就是字符串,还有各种日志分析就是看字符串怎么分析。Python设计的时候对这个东西有支持的,Python从Perl哲学学了很多,但是他想发展一下,就有了这个。我们讲一下Perl,我以前是写Perl的,但是是很早的时候,在2019年。我一开始上学学的是C和java,工作以后发现写东西太费劲,当时发现Perl这个东西很好就拿来用了,哪里好呢? 第一,PCRE,各类语言都有类似的库,特别是java里边,这个是和P
5、erl兼容的正德(音),同样处理速度来说它是最快的,它的正德(音)表达率是最宽泛的,所以很多语言过来要先兼容它,跟它有同样的表达能力。Python里面也有自己的正德(音),但是和这个不是很兼容。 第二个是CPAN,刚才讲了pip,类似这样的东西。在全球有各种各样的人写各种各样的Perl,你可以想一下从什么到什么,从你出了一个简单的字符串到你要煮一杯咖啡,到你研究人的DNA,研究一下卫星跑到哪,所有你能想到的想不到的,包括机器人。Perl有很多人研究机器人,怎么样控制机器人踢足球,有很多你想到想不到的东西都被大家写进去了。为了让Python也发展的快一点,所以后面有了pip,使Perl用起来很方
6、便。 第三个是速度,在摩尔定律仍然有效的时代,速度升高一倍,好像速度不是什么问题,大家都搞过大数据,或者将要搞大数据,我们做过一个分析,为什么你这个东西跑的这么慢,其实跑的最慢的不是这个框架需要怎么优化,而是你写的程序跑的最慢。其实java已经跑的很慢了,如果你这个东西比java跑的还慢你要改进算法。Perl比Python要快,Perl的效率和C是差不多的,Python明显慢一点。还有上下文相关类型、缩进语法,这是我最不喜欢的,Python是按缩进定位语法的,但是带来两个问题,一是使得ADE的自动缩进变得无所适从。我写了三个条件,这个ELSR放在这里明显代表不同的意思,比如我这里是大于一大于二
7、大于三,在这里是不大于一,不大于二,不大于三,这个时候你让ADE帮你自动缩进一下,ADE傻了,它不知道你要干吗。假如我现在一不小心写错了,可能应该写在这里,我写到了这里,有语法错吗?没有,能执行吗?能执行,不会出任何问题,但是结果就是不对,你要查到这个BUG是很困难的,尤其是当某些人把中间这段写的很长的时候,一翻篇看不到了。这是我个人比较诟病Python的一点。还有上下文相关类型,比如我们会写IF X大于3,X是什么东西?它是整数,Perl里X是什么不知道,它根据你出现在这我告诉你它是个什么,比如X可以是个数,比如X大于3代表X长度大于3。如果你说我取X里边的元素,它会告诉你要取数里的某个元素
8、,它说我要把这个东西付给某一个函数,它知道你可能要把这个数组拆开,代表一个参数,ADE更傻眼,这是要干吗。一个名字代表一个东西,这是我对他们比较诟病的两点。 还有易读性,Python这个东西看起来可以,首先它没有很多括号,像我们做代码看到括号不会读出来,直接略过,Python没有括号,Perl有很多乱七八糟的东西。当你看到一屏这个东西的时候好像这个人不是在说地球话。 为什么会有这么一篇?看到这么多人我就想到了我当时上学时候的一个理想。当时我老师问我你上学干吗,我说写代码,老师说写代码都没有前途,我说那我当老师。为什么?我说我先去代码界混几年,然后回去告诉新入学的大一学生,你师兄出去这么多年又回
9、来了,所以不要走这条路了。其实不是悲哀,我当时就想把我所知道的所有经验告诉大一学生,不要让他们走很多弯路,我走了很多弯路,给大家讲讲我走过的弯路。 2019年的时候步步高学习机basic,内存是640个字节,我当时用了各种办法把我写的东西写进去,之后告诉你写不进去了。这是很有意思的事情,你要在有限的资源内做很多事情,但是遇到了一个困难,我当时写求一千以内字数的算法,但是写不下去了,放不进去,写一百以内吧,可能是看我爸书里面讲说编程界有个很重要的概念叫递归,可以解决很多汉诺塔题,当时没有计算机这种东西,我就翻了各种书,终于找到汉诺塔这个定义,结果发现basic不支持。 到2019年的时候终于有了
10、一台奔三的计算机,可以写C代码,C语言支持。到2019年的时候有了一个很重要的东西走进我的生命,叫Linux,从此一发不可收拾。Linux没有教会我太多,但是它给我打开了一扇窗,让我知道原来还有另外一个世界。Part 2 后面就是java,2019年的时候开使用structs以前我们用的时候还没有到1.0,很恶心的地方就是不能引用,你要切很多。现在大家都不用这种东西了,当时建一个数据库麻烦的要死,各种配置文件,我当时郁闷的实在不行。后来搞了一个,你不要让我写了,一周要干的活,一天干完了,能用吗?我给你一个配置文件,以后都可以这么干,他说你这个东西要列为公司财产。 2019年我去了XX,开始接受
11、真正拿perl作为我的工作语言,因为我们当时用java。然后会用shell,还继续用java。2019年有一个重要的东西进入了我的生活叫lisp,在座的各位有研究这个东西的吗?lisp这个东西很简单,它就是没有语法的意思,它有一个语法就是括号括起来的先算,大家觉得这么一个东西有什么用呢?我后面再讲。 2019年我加入了AdMaster,我开始用phython、java和C。有一点很有意思的事情,当2019年我用C代码在奔三上写代码的时候,我问师兄第一个问题,我说师兄C语言有行号吗?你们有人有这个概念吗?就是basic程序是要有行号的?第一步我要干吗,第二步我要干吗,假如说你写123456789
12、,你会发现中间要写2,然后把3改成4,4改成5,这个程序不是这么些的,为了预期你往里面加东西,你不要写123456789,你要写10、20、30,你可以往里面加东西了,后来发现其实还不行,加十行都不够,后来是100、200、300,大家觉得很痛苦。后来我问师兄C里面有行号,行号是什么东西,我突然发现不用谢行号了?然后写java的时候,我问老师java里面有指征吗?中遇到后来我知道了C是不需要行号的,我们学了更多的语言以后慢慢改变了我们思考的方式。我不知道谁说过一句话,我们在用语言的同时,语言也在改变我们的思想。 可能有很多人是来自于外地的,外地人都有自己的方言,我以后说普通话的时候有一个感觉,
13、有很多事情我的思考方式是在用的方言思考,这个知识怎么这么别扭,然后再翻译过来。你脑袋里面有一些知识其实是和语言相关的,就像我们说普通话是这样的,所以要换一个方式,其实它的思考方式是不一样的。从这里面我们可以看到,大家看过英文原版的书会有一个发现,英文版的书最重要的是什么呢?第一是前言,第二是第一章,如果你把一本英文原版书前言和第一章非常认真的看完就可以了。我们中国人写书大头在后面,前面都是不重要的。编程语言同样也是这样的,发现在我在用C写basic,用java写C,我发现这个很不爽,其实拿java可以写perl,大家来讲这个什么意思,因为我写了一段代码,做了一件什么事情呢?我在里面连着用了八行
14、的替换,老大看蒙了说你这换成什么了,其实java不是这么做的,我意识到了,其实我已经开使用perl的思想开始思考外界的问题了,这个问题是不是对的,不知道。因为写basic的时候知道它有行号,现在我们用phython也一样,你思考的时候就是这样的,它可能不是那样的。phython里面有一些东西,在座的很多可能都比我强,因为我知道是这个东西的设计约束了我的脑袋。 然后我们讲一讲我们是如何学编程的,首先学编程是看别人的。我们看懂,看不懂变量名都没有替换,这个怎么用呢?第二步要开始理解,phython这个东西很容易读,大部分都是这样的,然后就是理解。第三步基本上就是改,很多时候我们是在改这个东西,为什
15、么?你要做一件事情,很多人表现出来有很多现成的库,我们想的是这个库拿过来没有那么好用,这不是你写的,这个时候怎么办?我们要改,找一找这个库别人是怎么用的,原来是这样用的,这三步过去了,我们终于开始写自己的代码了,因为每个公司都会有自己的代码库,就像我刚才讲的,你这个东西是公司的财富。其实每个公司有自己的代码库,每个人都有自己的风格。公司都有规定,你的代码写出来应该是什么样的,大家都按照这个去写,然后你写好了大家去用,这时候你可以说我精通这个语言了,因为我可以写库了。 然后就是Debug,第二个就是Profiling,工程师最讨厌的就是Debug,还有就是Profiling,你这个东西怎么出错了
16、,哪儿错了也不知道,非常头疼。但是你要学习一个语言,这两点不可避免最后都要学,不然的话出了问题你搞不定。 刚才讲的是我们表象上看起来,其实我们是怎么编程的呢?我们不是这么编程的,我们今天脱离phython这个东西,我们想一想我们真的是那样编程的吗?不是这样的,现在我要做一个一百以内的负数,我不要求你用什么语言,你脑袋里想的他定义一个什么,不是这样的,这是怎么算的,用人类能看懂的语言建了一个模式去解决这个问题。然后我们找了一个语言来实现,一般来说这个语言是我们最常用,又或者是我就会这一个,没有办法只能用它了。但是中间是有差距的,什么差距呢?比如说我要去前五位,有的同学说很简单,指定一下就可以了,
17、你考虑指征了,你考虑释放内存了吗?其实我们没有考虑那么多,怎么还有这么多乱七八糟的,然后我们Google了一下,这个怎么做,错了怎么办,然后继续循环。我们看一下欺世盗第二步为止,我们已经把问题在脑袋里面解决掉了,剩下的过程就是找一种语言去实现它,至于这个语言是什么。一般来讲,比如说我们抛开编程行业,你去钉一个钉子,你会拿一本书去钉吗?不会,因为HTML更适合干这个事,所以我们选语言,它的标准是更靠近我们解决这个领域,第二个是我们看起来要自然。我们有一个活动叫perl写出来是一篇诗,大家看太阳怎么样,星星怎么样,完全是人类不可理解的,所以我们一般不会这样。其实我们的做法是靠近人类实现,靠近人类语
18、言,这个语言存不存,我会选择一个更贴近的。 其实如果我们有能力的话,应该说这个东西是我写的。大家可以尝试一下,我要做一个什么事,其实作为的都不满足,这个是不是更高大上一些,这个语言是我写的,很多人在写这个东西。 我讲一下我们phython不自然的地方,第一个就是缩进语法,我们让它自动格式化,bug找不到了。第二个就是派生的Array变长了,我第一被phython坑了就是因为这个,讲一讲我被坑的环节。第一个是X等于rang(10),第二个是物X(5:)等于(1、2),当写完之后是这样的,X的长度变了,然后我们发现一个非常诡异的事情,怎么不对了,原来长度都是10的,怎么不对了,怎么解析不出来了,这
19、种情况还好。最要命的是X(3:5)等于rang(10),然后你发现你所有的都错误了,再也不用谢行号了,这个东西是你期望的吗?不是,当我们写下这个语句的时候,什么意思呢?从5以后不管多少从1到2,其实我想表达就是从这个开始往后,这个意思从3到5的rang的10,这个报错了,你要把两个改成五个,要么把它后面的扔掉,这是一种非常不友好的做法,你无缘无故把用户的数据扔掉,这时候其实应该报错告诉你,你这个指征越界了,Array会同时修改长度,这个bug是这样的。Part 3 它没有语法错误。还有一个是闭包,闭包的概念我想了好久好久,大概两年时间我终于明白它是什么,以前一直不懂,跟大家学,从网上看,各种用
20、法我都用过了还是不懂,突然搞了两年我明白了闭包是什么,给大家分享一下。 现在很火的各种语言,比如像speed,都会生成支持闭包,闭包是个什么样神奇的东西呢?它其实是一个函数,函数里边包含了一个变量,一般学术的说法叫它包含一个自由变量或者是非自由变量(我记不清了),使得这个函数在每次执行的时候会依赖于这个变量的值而改变。最简单的东西比如incf,这个函数代表加1,第一次调它你会得到1,第二次调它你会得到2,搞函数编程的同学该质疑我了。这内部保留了一个状态,你让我加1我给你换一个,这就是闭包。Incf一个什么什么,里面又incf一个什么什么,这里有一堆东西,我不用管,在这外面return一下,一个
21、函数里面定义一个函数,然后把它返回了,这定义一堆变量它知道了,这堆变量没有丢,被它存起来了,这就是incf。感觉很复杂,其实用最简单的基于对象来说,它就是一个类的实例,只不过是可以执行而已,一个类的实例有它的属性。假如只有一个方法,你每次调动只能用这个方法,这不就是闭包吗。 Python生成是支持闭包的,Python闭包是不完整的,简单问题复杂化。Incf一个fool,X=0,incf一个bug,X=X+1,return一个bug,我定义了这样一个包。这个闭包就是刚才我说的incf,第一次调给1,第二次调给2,就是做这件事。这代码有错误吗?这个代码让Python执行Python会报错,它说你在
22、这一行的时候这个X没有定义就被负值了,我很奇怪,生成支持闭包的语言里都不会报错,这就是正常的写法,Python会报错,我折腾了半天终于明白它为什么报错了。它说这个东西它是一个简单类型,因为它只是一个数字,或者是一个字符的简单类型,它不能被闭包所包进来,你要想做这件事怎么办?X=一个集合,X里面的X等于0,XX+1,我感到很莫名其妙,一个很简单的事情变得这么复杂。 这就是我们这一步所做的事情(见PPT)。在闭包这个问题上Python使我们简单问题复杂化,再就是版本兼容性,当时我用了一个小众的版本,用户群告诉我千万别升级2.7,2.7和2.6不兼容,升级就不能用了。但是这东西进退两难,升级不兼容,
23、不升级不能用。怎么办?其实我讲了这么多,语言是实现我们的思想的方法,先要有思想。举一个例子,我老婆经常问我,这个东西怎么写,我说你先不要写,先要想,想明白了再写。不是写一写就想明白了,而是想明白了再写,否则你写的可能要全部删掉。 为什么要写?这是一个很实际的问题,代码在你脑子里不能跑,你说这个东西我想明白了,结果呢?看不到,所以我们要写出来。这里有件趣事和大家分享一下,Perl有个版本叫Perl6,Perl6在实现之前怎么跑的呢?只能在人的脑袋里跑,你这个东西写没写错?用脑袋来看。我们首先要把它写出来,其次能执行的代码才是思想的表达,可能这个问题你觉得想明白了,写出来了,发现它执行不了,大家还
24、是看不懂,因为你写的不是那么契合大家的知识结构。其次是语言限制我们的思想,举一个例子,我要建这么一个结构,每次打开文件不用自己观察,它就给我关了,不管我程序是正常结束还是异常结束,有一个高大上的名字叫“装饰器”,做的事很简单,就是定义语法。你写了一个东西不代表原来的意思,或者原来的语言没有这个特性,它支持这个特性。Python给我们实现了“装饰器”的东西,你要去实现这个东西。但其实我们要做的事情不是这样的,比如这种结构我要画一块代码,每当出现这个关键字开头中间有什么东西我就干什么事情,这是一个架子,往大了讲是架构,往小了讲是语言的语法堂,你把一些想要表达的东西浓缩了一下,抽象一下,表达出来。其
25、实这是语言自我扩展的一种方式,在Python里面有“装饰器”,在C里面好像没有,Python有一点点。但是我们不会去想,我相信每个用Python的不会想我把这个东西拿出来,这么写太费劲了,用起来很舒服,它会限制我们的思想。第二个是语言甜区,当你一直用这个东西的时候会觉得很爽,我以前打乒乓球,乒乓球里的一个概念,球拍打时间久了你发现某一块地方坏的非常快,为什么?因为你的动作每次都这么打,这么打很舒服,“甜区”。语言也是一样,每次都这么写,突然这个东西没有了,好苦啊,不甜了。但是当你经常这么搞的时候你就不会扩展你的思想,所以说语言会限制你的思想。 使用语言的几个阶段,也是我讲为什么我们不要说精通P
26、ython,写好Python就够了,不是的。使用语言的几个阶段,一开始我不会写东西,首先我看一看XXX是怎么工作的,这个XXX可能就是Python,我看到Python是这么工作的,然后按照Python和使用Python的新方式解决问题,这个东西就形成了你的甜区。然后你学了第二种语言,现在有很多同学在学java,他以前是学Python的,现在学了java,java是要定义的,用Python的人可能没注意到。然后突然发现按YYY用YYY的方式解决问题。不自觉的你会做对比,这也是我们人类学习知识的方法,也是学习最快的,你学习了什么东西跟已知的联系对比起来你就会学的更快。然后升级了,我们开始用YYY按
27、XXX方法解决问题,我一般是新学一个语言,其实还是按照老套路去做,就像我一开始学java的时候,java是面向对象的,一个对象都没有,为什么面向对象,没有对象不是也行吗。再升级就是用KKK按YYY和、或、且XXX的方式解决问题,这个时候你已经基本上不区分它是什么语言,YYY或者Python,或者java,不知道,反正这样感觉更舒服一点就这么去搞。其实语言开发者跟你想的差不多,他也会从语言里面借鉴一些思想,当你提前知道这种思想的时候用起来就顺理成章。等到了这个阶段基本上你就不用去考虑它是KKK还是YYY还是XXX,因为所有的东西都变成了你的自然语言,你知道这个语言该怎么搞,这样搞可以解决什么问题
28、,那样搞可以解决什么问题。尤其当我们学了Python之后发现,从java跳到Python的同学会有这样的发现,java里面很多模式用不到。 我给大家对比几个我比较常用的,C,java,perl,Python,第一个是coding,就是写代码。第二个是libs,第三个是deploy,就是分发。之后是Profiling、debug。举一个例子,比如libs这一页,对于C来说可以加上C+,第一是因为速度快,Profiling里面C在这里当之无愧速度最快。还有它的视频处理库,现在除了互联网行业最赚钱的是游戏,其实现在还有一个是互联网金融,不知道它可以赚多少钱。但是已知可以赚钱的是游戏,有很多图形库都是
29、C,所以它的libs非常多,你说我拿java写一个游戏可以吗?可以,有人要吗?没有。你说我要打个拳皇,java写的,一个招出半天,谁用啊。Perl有很多人给它写库。Java也一样。Python我们有pip,Python如果解决了版本兼容的问题会更大行其道。还有Profiling,我现在感觉最爽的就是java的Profiling,Profiling跑一跑立马就知道出问题了。这个表大家可以参考一下。 这个可以略过不讲了,刚才已经讲的差不多了。写的很快,开发很快,原型试错快,库也很多。为什么不用Python?我刚才鼓励大家多学几种语言,多学几个就不用它了,因为它运行比较慢,第二个是GIL,这个东西使
30、得我们想要去做线上的同学勉为其难,不知道怎么搞。缩进语法,查错难,兼容性,各种华而不实的小特性,我经常记不住,但是我会去看。这里面有一个例子,前一段时间我改代码,把Python东西改成C,我在那不停的猜它在干吗,一行里面一个类似一个替换,算的我头晕脑胀,我也看不懂。 最重要的是Beyond Python,我们可以等Python更好,给它写很多库,但是我们也可以完全超过它,比如像scheme这种,scheme说我什么都不支持,我只支持define和apply。再是可以自定义语法结构,提供简单的包管理。我看到一篇文章很赞同,为什么java可以大行其道,当时在C+占市场份额很高的时候为什么java可
31、以大行其道?C+很不爽的一点是内存管理复杂,再是库用起来很费劲,java是不管你在windows下跑,在Linux下跑,在手机下跑,这个东西变完之后都可以用。说你想管理什么包,没问题,一大堆东西扔过来一加就可以用了,这个东西太爽了。 Java的deploy就是扔过去大家都可以用。C也是,只要你的环境跟我一样,你跑出来的结果就是一样的,java不用,版本一样吗?都一样的跑出来的结果是一样的,如果不一样就要重新编一版。但是跟这两相比我自己感觉比较弱的就是这个。Python很快就写完了,结果没有库,我们要在某个机器上安装库,终于弄好了结果又缺个什么库,烦死了。所以一定要提供简单的包管理。为开发工具提
32、供良好的接口,Python和java都不错,虽然Python的缩进语法上有时候ADE无所适从,但起码可以点一下告诉你什么方法。可能大家没有这个感触,像以前我写C的时候,写完这个函数参数是什么看一看就知道了,痛苦的要死。 我的演讲就到这里。大家有什么问题吗? 主持人:现在是有奖提问,我们这准备了两个礼品,一个是Top100精美笔记本,另外一个是网易提供的T恤。 提问1:我们使用Python程序,像我写的从前到后,后面是Python脚本,我现在有时候出现怪异的异常,调适起来非常麻烦,问一下您这里有没有比较好的调适的方式? 刘喆:其实我也没有(开玩笑)。当年我们去做一个论坛,当时也问到了类似的问题,大家在写的时候感觉很麻烦,怎么样好用一点,我们这些研究者得出的一致结论是没有好的办法,最好的办法是Perl,这个东西是一个又简单又不需要思考又万能的东西。为什么呢?一段代码两千行,出错了,中间打一行打Perl,第五百行打Perl,很快就找到了。或者你可以学一下ja
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1