如何看待德与才的关系 PyPy 与 Pyston 的未来

Pyston——基于LLVM和现代JIT技术的开源Python实现 - CSDN博客
Pyston——基于LLVM和现代JIT技术的开源Python实现
本月初,Kevin Modzelewski在上宣布了他们正在开发的一款开源Python实现——Pyston。该项目的目标是开发出一款高性能的Python实现,使Python跻身如C++等传统系统级语言所统治的领域。
Dropbox内部有很多项目是用Python编写的。Python之父Guido van Rossum从Google离职后也。随着业务规模的增长,性能问题也愈加突出。虽然通过其他语言改写应用可以获得性能改进,但出于对Python的钟爱,Dropbox的工程师们希望改变Python的性能。在使用静态编译做了一些实验之后,他们放弃了这种策略。鉴于Google的v8对JavaScript性能的极大改进,他们决定采用类似的技术来改进Python的性能。
现在已经有了一些采用了JIT技术的Python实现,比如PyPy,它使用的是技术,大幅改进了Python的性能,再如Jython和IronPython,它们则构建于大量应用JIT技术的成熟虚拟机之上。那为什么还要引入一种新实现呢?文中给出的解释是:
简单地说,这是因为我们认为前景最好的技术与现有实现不兼容。例如,由于巨大的性能优势,JavaScript世界已经从基于Trace的JIT转向基于方法的JIT(每次编译一个方法)。在Python上是否有同样的优势尚不得而知,但因为这两种方法从根本上是不兼容的,所以要回答这个问题,唯一的方法是构建一个新的基于方法的JIT。
还有一点,他们计划使用保守的垃圾收集器,以便高效。
当然,从零开始创建一个语言实现工作量非常大。不过Pyston准备基于LLVM构建,这会方便很多。
文中还介绍了Pyston的工作方式:
从高层看,Pyston接受解析好的Python代码,并将其转换为LLVM中间代码(IR)。然后IR经由LLVM优化器处理,再被传送给LLVM JIT引擎,最后得到可执行的机器代码。
Pyston的代码已经在上开放出来,Dropbox希望和Python及JIT社区合作推进其开发。项目页面上还介绍了Pyston的一些,比如编译层次、栈上替换和内联等,感兴趣的读者可以参考。
在Pyston之前,Google的几位工程师曾发起过项目,目标是将Python的性能提高5倍,主要想法是为
CPython 添加一个基于 LLVM 的 JIT 编译器,但是该项目以失败告终。关于该项目的经验与教训,有两篇文章可以参考:1.;2.&。
关于Pyston,在Hacker News上也有一些。比如haberman指出,基于方法的JIT编译器其实是更为传统的方式,而基于Trace的最近5~10年才流行起来的。尽管V8确实采用的是基于方法的JIT,Mozilla也放弃了基于Trace的JIT
TraceMonkey,但是LuaJIT却是最快的动态语言实现之一,而且采用的就是基于Trace的JIT。LuaJIT的作者Mike PallTraceMonkey没有取得很好的性能,更大程度上是因为尝试将Trace绑到现有的虚拟机上,而不是因为基于Trace的JIT技术的缺点。
Facebook也为优化其PHP应用的性能做了很多工作,现在的解决方案是,这种方案可以说是成功的。那Pyston的前景如何呢?我们拭目以待。
本文已收录于以下专栏:
相关文章推荐
LLVM从设计之初就考虑了解释执行的功能,这非常其作为一款跨平台的中间字节码来使用,可以方便地跨平台运行。又具有编译型语言的优势,非常的方便。
我们使用的LLVM3.6版,移除了原版JIT,改换成了新...
LLVM平台,短短几年间,改变了众多编程语言的走向,也催生了一大批具有特色的编程语言的出现,不愧为编译器架构的王者,也荣获2012年ACM软件系统奖。
一、  说明
据说Android 2.2的虚拟机dalvik使用了JIT技术,使其运行速度快了5倍。dalvik解释并执行程序,JIT技术主要是对多次运行的代码进行编译,当再次调用时使用编译之后的机器...
现代半导体IC芯片封装技术——通史编者按:这篇文章成文于日发表在《大众硬件》上,被连载了2期。这是一篇很好的技术文章,也是我拿得出手可以炫耀的作品。文章中有一处图片错误,我直到自己拿...
经典数据结构教科书中,“表”是数据结构的一个大家族。其中,有顺序表(数组)、单向链表、双向链表、循环链表等等。我们今天聊的不是这些,而是“表”中的异类——哈希表(Hash Table)。
即时编译回顾
HotSpot 虚拟机执行 Java 程序时,先通过解释器对代码解释执行,发现某个方法或代码块执行比较频繁后,对热点代码进行编译,编译后生成与本地平台相关的机器码,再去执行机器码获得较...
具体参考《深入理解JVM虚拟机》第十一章
他的最新文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)&p&Python的黑魔法当然是各种自省和动态绑定了。&/p&&br&&p&举个例子,Python可以重新绑定解释器的excepthook,这样当程序异常结束时就可以做一些自定义的处理,我自己就一直拿这个配合ipdb进行debug。用以下代码声明一个ExceptionHook:&/p&&div class=&highlight&&&pre&&code class=&language-python3&&&span class=&k&&class&/span& &span class=&nc&&ExceptionHook&/span& &span class=&p&&:&/span&
&span class=&n&&instance&/span& &span class=&o&&=&/span& &span class=&k&&None&/span&
&span class=&k&&def&/span& &span class=&nf&&__call__&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&,&/span& &span class=&o&&*&/span&&span class=&n&&args&/span&&span class=&p&&,&/span& &span class=&o&&**&/span&&span class=&n&&kwargs&/span&&span class=&p&&)&/span& &span class=&p&&:&/span&
&span class=&k&&if&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&instance&/span& &span class=&ow&&is&/span& &span class=&k&&None&/span&&span class=&p&&:&/span&
&span class=&kn&&from&/span& &span class=&nn&&IPython.core&/span& &span class=&k&&import&/span& &span class=&n&&ultratb&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&instance&/span& &span class=&o&&=&/span& &span class=&n&&ultratb&/span&&span class=&o&&.&/span&&span class=&n&&FormattedTB&/span&&span class=&p&&(&/span&&span class=&n&&mode&/span& &span class=&o&&=&/span& &span class=&s&&&Plain&&/span&&span class=&p&&,&/span& &span class=&n&&color_scheme&/span& &span class=&o&&=&/span& &span class=&s&&&Linux&&/span&&span class=&p&&,&/span& &span class=&n&&call_pdb&/span& &span class=&o&&=&/span& &span class=&mi&&1&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&instance&/span&&span class=&p&&(&/span&&span class=&o&&*&/span&&span class=&n&&args&/span&&span class=&p&&,&/span& &span class=&o&&**&/span&&span class=&n&&kwargs&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&&p&然后&/p&&div class=&highlight&&&pre&&code class=&language-python3&&&span class=&kn&&import&/span& &span class=&nn&&sys&/span&
&span class=&n&&sys&/span&&span class=&o&&.&/span&&span class=&n&&exceptionhook&/span& &span class=&o&&=&/span& &span class=&n&&ExceptionHook&/span&&span class=&p&&()&/span&
&/code&&/pre&&/div&&p&重设完exceptionhook后,一旦你的代码抛出异常,整个解释器的环境都会被ipdb接管,然后就可以像交互模式下那样使用了。通常我会在里面查一下栈,把必要的对象pickle一下,这样以后复现错误也比较容易。&/p&&p&由于IPython是非GUI的程序,所以即便在SSH里也可以使用这招,完美解决SSH缺少IDE难以debug的窘境。&/p&&p&动态绑定的另一个用处,就是当程序依赖一个修改过的库时,可以把修改的部分剥离出来,在运行时动态绑定到对应的库上去就行。如果修改的是成员方法,需要这样绑定:&/p&&div class=&highlight&&&pre&&code class=&language-python3&&&span class=&kn&&from&/span& &span class=&nn&&types&/span& &span class=&k&&import&/span& &span class=&n&&MethodType&/span&
&span class=&k&&def&/span& &span class=&nf&&_foo&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&,&/span& &span class=&o&&...&/span&&span class=&p&&):&/span&
&span class=&k&&pass&/span&
&span class=&n&&obj&/span&&span class=&o&&.&/span&&span class=&n&&foo&/span& &span class=&o&&=&/span& &span class=&n&&MethodType&/span&&span class=&p&&(&/span&&span class=&n&&_foo&/span&&span class=&p&&,&/span& &span class=&n&&obj&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&&br&&p&顺带提一下,pickle也是个非常好用的工具,尽管序列化并不是python的专利。pickle可以用来保存各种运行过程中的对象:&/p&&div class=&highlight&&&pre&&code class=&language-python3&&&span class=&kn&&import&/span& &span class=&nn&&pickle&/span&
&span class=&n&&pickle&/span&&span class=&o&&.&/span&&span class=&n&&dump&/span&&span class=&p&&(&/span&&span class=&n&&xxx&/span&&span class=&p&&,&/span& &span class=&nb&&open&/span&&span class=&p&&(&/span&&span class=&s&&&xxx.dump&&/span&&span class=&p&&,&/span& &span class=&s&&&w&&/span&&span class=&p&&))&/span&
&span class=&n&&yyy&/span& &span class=&o&&=&/span& &span class=&n&&pickle&/span&&span class=&o&&.&/span&&span class=&n&&load&/span&&span class=&p&&(&/span&&span class=&nb&&open&/span&&span class=&p&&(&/span&&span class=&s&&&yyy.dump&&/span&&span class=&p&&))&/span&
&/code&&/pre&&/div&&p&pickle可以减少很多工作量,尤其是在复现bug时,把正确部分的运行结果pickle下来,这样每次可以从pickle的位置开始运行。跑多个相似的baseline时也有很好的效果。不足的是pickle比较吃硬盘,pickle一堆东西后很容易就十几个G了,而且pickle不能序列化动态生成的对象,比如lambda表达式或者上面提到的动态绑定产生的成员方法。&/p&&br&&p&自省方面,Python可以通过dir()和help()函数分别取得对象下成员的列表和帮助,这个在找不到库文档的时候非常好用。只要开发者在函数下面写了注释,就能在help中看到。&/p&&br&&p&除了上面提到的这些特性,python还有一堆小trick,其他回答里也提到了一些。虽然其中很多是语法糖,不过用好它们可以让程序更pythonic:&/p&&ol&&li&类中用__slots__将成员静态化,可以节省大量内存。&/li&&li&装饰器,常见用途如函数计时,亦可用来产生新的函数签名。函数签名会影响传参检查和ide补全,对带不定长参数的函数非常有用。很多库中都会用这种方法来兼容不同版本的API。&/li&&li&生成器,对于只需遍历的数据可以节省大量内存。&/li&&li&*和**参数展开。典型的例子是zip(*list_x)和chain(*list_x),分别相当于转置和concatenate。&/li&&li&if __name__ == &__main__&: 检查是否作为主程序调用,用multiprocessing并行时主程序得用这个框起来。&/li&&li&enumerate,例如将一个list变成list2index可以用dict([(x, i) for i, x in enumerate(list_x)])&/li&&li&namedtuple,生成类似于C语言的结构体,同时支持tuple的所有语法。&/li&&li&defaultdict,做统计时不用初始化的dict,可以用lambda实现嵌套构造defaultdict(lambda : defaultdict(int)),甚至递归字典tree = lambda : defaultdict(tree)。&/li&&/ol&&br&&p&是不是干货满满 = ̄ω ̄=&/p&
Python的黑魔法当然是各种自省和动态绑定了。 举个例子,Python可以重新绑定解释器的excepthook,这样当程序异常结束时就可以做一些自定义的处理,我自己就一直拿这个配合ipdb进行debug。用以下代码声明一个ExceptionHook:class ExceptionHook :
instance…
因为教学的目的和做项目的目的是完全相反的.&br&教学的目的就是让学生尽量多踩坑, 踩到的越多提高的越快. 而工作时尽量避坑, 最好是打个响指项目就完成了.&br&&br&C语言明显更底层&br&更底层意味着很多功能要自己实现, 在实现过程中学生会对底层硬件, 操作系统, 算法的细节有进一步的感性认识. 教一门语言还能连带学到许多其他知识, 而且社会上的实用度不低, 再没有比C更好的讲解对象了.&br&对C++了解不深, 但感觉这个语言特性很多很复杂, 搞定了C++再搞其他高级语言都是小菜一碟了.&br&&br&python和php这类脚本语言都是高度封装化了的语言, 对学生来说太&甜&了, 对成长的帮助没有C/C++大
因为教学的目的和做项目的目的是完全相反的. 教学的目的就是让学生尽量多踩坑, 踩到的越多提高的越快. 而工作时尽量避坑, 最好是打个响指项目就完成了. C语言明显更底层 更底层意味着很多功能要自己实现, 在实现过程中学生会对底层硬件, 操作系统, 算法的细…
之前写了一个1.0版,现在把更加完整的2.0版奉上。&br&1.0版已经被我杀掉了。&br&--------------------------------------2.0版-------------------------------------------------------------------&br&&b&Attention&/b&:为了解释得通俗易懂,所以很多概念没有描述的很准确,很多只是“意思意思”,所以大家重在意会哈。如果各位知友有更好的解释和讲解的方法,还请在评论区不吝赐教。&br&学习python有一段时间了,对于装饰器的理解又多了一些,现在我重新再写一次对于装饰器的理解。&br&在讲之前我需要先铺垫一下基础知识,如果你已经掌握了就请跳过。&br&--------------------------------------基础知识分割线-----------------------------------------------------&br&1、&b&万物皆对象&/b&。&br&在python中,不管什么东西都是对象。对象是什么东西呢?&br&对象就是你可以用来随意使用的模型。当你需要的时候就拿一个,不需要就让它放在那,垃圾回收机制会自动将你抛弃掉的对象回收。&br&可能对这个理解有一点云里雾里的感觉,甚至还觉得对这个概念很陌生。其实如果你都学到装饰器这里了,你已经使用过不少对象啦。&br&比如,我写了一个函数:&br&&div class=&highlight&&&pre&&code class=&language-python&&&span class=&k&&def&/span& &span class=&nf&&cal&/span&&span class=&p&&(&/span&&span class=&n&&x&/span&&span class=&p&&,&/span& &span class=&n&&y&/span&&span class=&p&&):&/span&
&span class=&n&&result&/span& &span class=&o&&=&/span& &span class=&n&&x&/span& &span class=&o&&+&/span& &span class=&n&&y&/span&
&span class=&k&&return&/span& &span class=&n&&result&/span&
&/code&&/pre&&/div&这时,你可以说,你创造了一个叫做cal的函数对象。&br&然后,你这样使用了它:&br&&div class=&highlight&&&pre&&code class=&language-python&&&span class=&n&&cal&/span&&span class=&p&&(&/span&&span class=&mi&&1&/span&&span class=&p&&,&/span&&span class=&mi&&2&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&或者,你这样使用了它:&br&&div class=&highlight&&&pre&&code class=&language-text&&calculate = cal
calculate(1,2)
&/code&&/pre&&/div&在第一种方式下,你直接使用了cal这个函数对象;&br&在第二种方式下,你把一个名为calculate的变量指向了cal这个函数对象。如果各位对类的使用很熟悉的话,可以把这个过程看作“实例化”。&br&也就是说,对象,就像是一个模子,当你需要的时候,就用它倒一个模型出来,每一个模型可以有自己不同的名字。在上面的例子中,calculate是一个模型,而你写的cal函数就是一个模子。&br&&br&2、请理解函数&b&带括号和不带括号&/b&时分别代表什么意思。&br&在上一个例子中,如果你只是写一个cal(也就是没有括号),那么此时的cal仅仅是代表一个函数对象;当你这样写cal(1, 2)时,就是在告诉编译器“执行cal这个函数”。&br&&br&3、请确保能够理解&b&带星号的参数&/b&是什么意思。&br&这个属于函数基础,要是你还没有听说过,那么就该回去好好复习一下了。具体讲解我就略过了。&br&----------------------------------------------正文分割线---------------------------------------------------&br&1、装饰器是什么?&br&装饰器,顾名思义,就是用来“装饰”的。&br&它长这个样:&br&&div class=&highlight&&&pre&&code class=&language-text&&@xxx
&/code&&/pre&&/div&其中&xxx&是你的装饰器的名字。&br&它能装饰的东西有:函数、类&br&&br&2、为什么我需要装饰器?&br&有一句名言说的好(其实是我自己说的):&br&“每一个轮子都有自己的用处”&br&所以,每一个装饰器也有自己的用处。&br&装饰器主要用来“偷懒”(轮子亦是如此)。&br&比如:&br&你写了很多个简单的函数,你想知道在运行的时候是哪些函数在执行,并且你又觉得这个没有必要写测试,只是想要很简单的在执行完毕之前给它打印上一句“Start”,那该怎么办呢?你可以这样:&br&&div class=&highlight&&&pre&&code class=&language-pytb&&&span class=&x&&def func_name(arg):&/span&
&span class=&x&&
print 'Start func_name'&/span&
&span class=&x&&
sentences&/span&
&/code&&/pre&&/div&这样做没有错,but, 你想过没有,难道你真的就想给每一个函数后面都加上那么一句吗?等你都运行一遍确定没有问题了,再回来一个一个的删掉print不觉得麻烦吗?什么?你觉得写一个还是不麻烦的,那你有十个需要添加的函数呢?二十个?三十个?(请自行将次数加到超过你的忍耐阈值)……&br&如果你知道了装饰器,情况就开始渐渐变得好一些了,你知道可以这样写了:&br&&div class=&highlight&&&pre&&code class=&language-python&&&span class=&k&&def&/span& &span class=&nf&&log&/span&&span class=&p&&(&/span&&span class=&n&&func&/span&&span class=&p&&):&/span&
&span class=&k&&def&/span& &span class=&nf&&wrapper&/span&&span class=&p&&(&/span&&span class=&o&&*&/span&&span class=&n&&arg&/span&&span class=&p&&,&/span& &span class=&o&&**&/span&&span class=&n&&kw&/span&&span class=&p&&):&/span&
&span class=&k&&print&/span& &span class=&s&&'Start &/span&&span class=&si&&%s&/span&&span class=&s&&'&/span& &span class=&o&&%&/span& &span class=&n&&func&/span&
&span class=&k&&return&/span& &span class=&n&&func&/span&&span class=&p&&(&/span&&span class=&o&&*&/span&&span class=&n&&arg&/span&&span class=&p&&,&/span& &span class=&o&&**&/span&&span class=&n&&kw&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&n&&wrapper&/span&
&span class=&nd&&@log&/span&
&span class=&k&&def&/span& &span class=&nf&&func_a&/span&&span class=&p&&(&/span&&span class=&n&&arg&/span&&span class=&p&&):&/span&
&span class=&k&&pass&/span&
&span class=&nd&&@log&/span&
&span class=&k&&def&/span& &span class=&nf&&func_b&/span&&span class=&p&&(&/span&&span class=&n&&arg&/span&&span class=&p&&):&/span&
&span class=&k&&pass&/span&
&span class=&nd&&@log&/span&
&span class=&k&&def&/span& &span class=&nf&&func_c&/span&&span class=&p&&(&/span&&span class=&n&&arg&/span&&span class=&p&&):&/span&
&span class=&k&&pass&/span&
&/code&&/pre&&/div&其中,log函数是装饰器。&br&把装饰器写好了之后,只需要把需要装饰的函数前面都加上@log就可以了。在这个例子中,我们一次性就给三个函数加上了print语句。&br&可以看出,装饰器在这里为我们节省了代码量,并且在你的函数不需要装饰的时候直接把@log去掉就可以了,只需要用编辑器全局查找然后删除即可,快捷又方便,不需要自己手工的去寻找和删除print的语句在哪一行。&br&-----------------------------------------------重点分割线--------------------------------------------------&br&3、装饰器原理&br&在上一段中,或许你已经注意到了&log&b&&u&&i&函数&/i&&/u&&/b&是装饰器&这句话。没错,装饰器是&b&函数。&/b&&br&接下来,我将带大家探索一下,装饰器是怎么被造出来的,来直观的感受一下装饰器的原理。&br&先回到刚才的那个添加'Start'问题。&br&假设你此时还不知道装饰器。&br&将会以Solution的方式呈现。&br&S1 我有比在函数中直接添加print语句更好的解决方案!&br&于是你这样做了:&br&&div class=&highlight&&&pre&&code class=&language-python&&&span class=&k&&def&/span& &span class=&nf&&a&/span&&span class=&p&&():&/span&
&span class=&k&&pass&/span&
&span class=&k&&def&/span& &span class=&nf&&b&/span&&span class=&p&&():&/span&
&span class=&k&&pass&/span&
&span class=&k&&def&/span& &span class=&nf&&c&/span&&span class=&p&&():&/span&
&span class=&k&&pass&/span&
&span class=&k&&def&/span& &span class=&nf&&main&/span&&span class=&p&&():&/span&
&span class=&k&&print&/span& &span class=&s&&'Start a'&/span&
&span class=&n&&a&/span&&span class=&p&&()&/span&
&span class=&k&&print&/span& &span class=&s&&'Start b'&/span&
&span class=&n&&b&/span&&span class=&p&&()&/span&
&span class=&k&&print&/span& &span class=&s&&'Start c'&/span&
&span class=&n&&c&/span&&span class=&p&&()&/span&
&/code&&/pre&&/div&感觉这样做好像没什么错,并且还避免了修改原来的函数,如果要手工删改print语句的话也更方便了。嗯,有点进步了,很不错。&br&S2 我觉得刚刚那个代码太丑了,还可以再优化一下!&br&于是你这样写了:&br&&div class=&highlight&&&pre&&code class=&language-python&&&span class=&k&&def&/span& &span class=&nf&&a&/span&&span class=&p&&():&/span&
&span class=&k&&pass&/span&
&span class=&k&&def&/span& &span class=&nf&&b&/span&&span class=&p&&():&/span&
&span class=&k&&pass&/span&
&span class=&k&&def&/span& &span class=&nf&&c&/span&&span class=&p&&():&/span&
&span class=&k&&pass&/span&
&span class=&k&&def&/span& &span class=&nf&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&func&/span&&span class=&p&&):&/span&
&span class=&k&&print&/span& &span class=&s&&'Start &/span&&span class=&si&&%s&/span&&span class=&s&&'&/span&&span class=&o&&%&/span& &span class=&n&&func&/span&
&span class=&n&&func&/span&&span class=&p&&()&/span&
&span class=&k&&def&/span& &span class=&nf&&main&/span&&span class=&p&&():&/span&
&span class=&n&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&)&/span&
&span class=&n&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&b&/span&&span class=&p&&)&/span&
&span class=&n&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&c&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&你现在写了一个函数来代替你为每一个函数写上print语句,好像又节省了不少时间。你欣喜的喝了一口coffee,对自己又一次做出了进步感到很满意。&br&嗯,确实是这样。&br&于是你选择出去上了个厕所,把刚刚憋的尿全部都排空(或许还有你敲代码时喝的coffee)。&br&回来之后,顿时感觉神清气爽!你定了定神,看了看自己刚才的“成果”,似乎又感到有一些不满意了。&br&因为你想到了会出现这样的情况:&br&&div class=&highlight&&&pre&&code class=&language-text&&def main():
decorator(a)
m = decorator(b)
n = decorator(c) + m
for i in decorator(d):
&/code&&/pre&&/div&来,就说你看到满篇的decorator你晕不晕!大声说出来!&br&S3
你又想了一个更好的办法。&br&于是你这样写了:&br&&div class=&highlight&&&pre&&code class=&language-python&&&span class=&k&&def&/span& &span class=&nf&&a&/span&&span class=&p&&():&/span&
&span class=&k&&pass&/span&
&span class=&k&&def&/span& &span class=&nf&&b&/span&&span class=&p&&():&/span&
&span class=&k&&pass&/span&
&span class=&k&&def&/span& &span class=&nf&&c&/span&&span class=&p&&():&/span&
&span class=&k&&pass&/span&
&span class=&k&&def&/span& &span class=&nf&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&func&/span&&span class=&p&&):&/span&
&span class=&k&&print&/span& &span class=&s&&'Start &/span&&span class=&si&&%s&/span&&span class=&s&&'&/span& &span class=&o&&%&/span& &span class=&n&&func&/span&
&span class=&k&&return&/span& &span class=&n&&func&/span&
&span class=&n&&a&/span& &span class=&o&&=&/span& &span class=&n&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&)&/span&
&span class=&n&&b&/span& &span class=&o&&=&/span& &span class=&n&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&b&/span&&span class=&p&&)&/span&
&span class=&n&&c&/span& &span class=&o&&=&/span& &span class=&n&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&c&/span&&span class=&p&&)&/span&
&span class=&k&&def&/span& &span class=&nf&&main&/span&&span class=&p&&():&/span&
&span class=&n&&a&/span&&span class=&p&&()&/span&
&span class=&n&&b&/span&&span class=&p&&()&/span&
&span class=&n&&c&/span&&span class=&p&&()&/span&
&/code&&/pre&&/div&这下总算是把名字给弄回来了,这样就不会晕了。你的嘴角又一次露出了欣慰的笑容(内心OS:哈哈哈,爷果然很6!)。于是你的手习惯性的端起在桌上的coffee,满意的抿了一口。&br&coffee的香味萦绕在唇齿之间,你满意的看着屏幕上的代码,突然!脑中仿佛划过一道闪电!要是a、b、c 三个函数带参数我该怎么办?!&br&你放下coffee,手托着下巴开始思考了起来,眉头紧锁。&br&像这样写肯定不行:&br&&div class=&highlight&&&pre&&code class=&language-text&&a = decorator(a(arg))
&/code&&/pre&&/div&此时的本应该在decorator中做为一个参数对象的a加上了括号,也就是说,a在括号中被执行了!你只是想要a以函数对象的形式存在,乖乖的跑到decorator中当参数就好了。执行它并不是你的本意。&br&那该怎么办呢?&br&你扶了扶眼镜,嘴里开始念念有词“&b&万物皆对象&/b&,&b&万物皆对象&/b&……”&br&你的额头上开始渐渐的渗出汗珠。&br&突然,你的身后的背景暗了下来,一道光反射在眼镜上!不自觉的说了句&br&“真相はひとつだけ”!&br&S4 你飞速的写下如下代码。&br&&div class=&highlight&&&pre&&code class=&language-python&&&span class=&k&&def&/span& &span class=&nf&&a&/span&&span class=&p&&(&/span&&span class=&n&&arg&/span&&span class=&p&&):&/span&
&span class=&k&&pass&/span&
&span class=&k&&def&/span& &span class=&nf&&b&/span&&span class=&p&&(&/span&&span class=&n&&arg&/span&&span class=&p&&):&/span&
&span class=&k&&pass&/span&
&span class=&k&&def&/span& &span class=&nf&&c&/span&&span class=&p&&(&/span&&span class=&n&&arg&/span&&span class=&p&&):&/span&
&span class=&k&&pass&/span&
&span class=&k&&def&/span& &span class=&nf&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&func&/span&&span class=&p&&):&/span&
&span class=&k&&def&/span& &span class=&nf&&wrapper&/span&&span class=&p&&(&/span&&span class=&o&&*&/span&&span class=&n&&arg&/span&&span class=&p&&,&/span& &span class=&o&&**&/span&&span class=&n&&kw&/span&&span class=&p&&)&/span&
&span class=&k&&print&/span& &span class=&s&&'Start &/span&&span class=&si&&%s&/span&&span class=&s&&'&/span& &span class=&o&&%&/span& &span class=&n&&func&/span&
&span class=&k&&return&/span& &span class=&n&&func&/span&&span class=&p&&(&/span&&span class=&o&&*&/span&&span class=&n&&arg&/span&&span class=&p&&,&/span& &span class=&o&&**&/span&&span class=&n&&kw&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&n&&wrapper&/span&
&span class=&n&&a&/span& &span class=&o&&=&/span& &span class=&n&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&)&/span&
&span class=&n&&b&/span& &span class=&o&&=&/span& &span class=&n&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&b&/span&&span class=&p&&)&/span&
&span class=&n&&c&/span& &span class=&o&&=&/span& &span class=&n&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&c&/span&&span class=&p&&)&/span&
&span class=&k&&def&/span& &span class=&nf&&main&/span&&span class=&p&&():&/span&
&span class=&n&&a&/span&&span class=&p&&(&/span&&span class=&n&&arg&/span&&span class=&p&&)&/span&
&span class=&n&&b&/span&&span class=&p&&(&/span&&span class=&n&&arg&/span&&span class=&p&&)&/span&
&span class=&n&&c&/span&&span class=&p&&(&/span&&span class=&n&&arg&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&decorator函数返回的是wrapper, wrapper是一个函数对象。而a = decorator(a)就相当于是把 a 指向了 wrapper, 由于wrapper可以有参数,于是变量 a 也可以有参数了!&br&终于!你从焦灼中解脱了出来!&br&不过, 有了前几次的经验,你这一次没有笑。&br&你又仔细想了想,能不能将a = decorator(a)这个过程给自动化呢?&br&于是你的手又开始在键盘上飞快的敲打,一会儿过后,你终于完成了你的“作品”。&br&你在python中添加了一个语法规则,取名为“@”,曰之“装饰器”。&br&你此时感觉有些累了, 起身打开门, 慢步走出去,深吸一口气,感觉阳光格外新鲜。&br&你的脸上终于露出了一个大大的笑容。&br&-------------------------------乱侃结束分割线------------------------------------------------------------&br&讲到这里,我想大家应该差不多都明白了装饰器的原理。&br&在评论中有知友问到,要是我的装饰器中也有参数该怎么办呢?&br&要是看懂了刚才添加参数的解决方案,也就不觉得难了。&br&再加一层就解决了。&br&&div class=&highlight&&&pre&&code class=&language-python&&&span class=&k&&def&/span& &span class=&nf&&decorator&/span&&span class=&p&&(&/span&&span class=&n&&arg_of_decorator&/span&&span class=&p&&):&/span&
&span class=&k&&def&/span& &span class=&nf&&log&/span&&span class=&p&&(&/span&&span class=&n&&func&/span&&span class=&p&&):&/span&
&span class=&k&&def&/span& &span class=&nf&&wrapper&/span&&span class=&p&&(&/span&&span class=&o&&*&/span&&span class=&n&&arg&/span&&span class=&p&&,&/span& &span class=&o&&**&/span&&span class=&n&&kw&/span&&span class=&p&&):&/span&
&span class=&k&&print&/span& &span class=&s&&'Start &/span&&span class=&si&&%s&/span&&span class=&s&&'&/span& &span class=&o&&%&/span& &span class=&n&&func&/span&
&span class=&c&&#TODO Add here sentences which use arg_of_decorator &/span&
&span class=&k&&return&/span& &span class=&n&&func&/span&&span class=&p&&(&/span&&span class=&o&&*&/span&&span class=&n&&arg&/span&&span class=&p&&,&/span& &span class=&o&&**&/span&&span class=&n&&kw&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&n&&wrapper&/span&
&span class=&k&&return&/span& &span class=&n&&log&/span&
&/code&&/pre&&/div&感谢阅读 : )&br&----------------------------------------------------------------------------------------------------------------&br&&b&请大家着重理解思路。&/b&&br&答主是一名在校大学生,主修英语专业,目前大二,希望能够和各位知友多多交流。要是有同道中人关注我就更好了!&br&我先撤退了。&br&撒花!??ヽ(?▽?)ノ?
之前写了一个1.0版,现在把更加完整的2.0版奉上。 1.0版已经被我杀掉了。 --------------------------------------2.0版------------------------------------------------------------------- Attention:为了解释得通俗易懂,所以很多概念没有描述的很准…
我很喜欢用python,用python处理数据是家常便饭,从事的工作涉及nlp,算法,推荐,数据挖掘,数据清洗,数据量级从几十k到几T不等,我来说说吧&br&百万级别数据是小数据,python处理起来不成问题,python处理数据还是有些问题的&br&Python处理大数据的劣势:&br&1. python线程有gil,通俗说就是多线程的时候只能在一个核上跑,浪费了多核服务器。在一种常见的场景下是要命的:并发单元之间有巨大的数据共享或者共用(例如大dict),多进程会导致内存吃紧,多线程则解决不了数据共享的问题,单独的写一个进程之间负责维护读写这个数据不仅效率不高而且麻烦&br&2. python执行效率不高,在处理大数据的时候,效率不高,这是真的,pypy(一个jit的python解释器,可以理解成脚本语言加速执行的东西)能够提高很大的速度,但是pypy不支持很多python经典的包,例如numpy(顺便给pypy做做广告,土豪可以捐赠一下&a href=&///?target=http%3A//pypy.org/numpydonate.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PyPy - Call for donations&i class=&icon-external&&&/i&&/a&)&br&3. 绝大部分的大公司,用java处理大数据不管是环境也好,积累也好,都会好很多&br&Python处理数据的优势(不是处理大数据):&br&1. 异常快捷的开发速度,代码量巨少&br&2. 丰富的数据处理包,不管正则也好,html解析啦,xml解析啦,用起来非常方便&br&3. 内部类型使用成本巨低,不需要额外怎么操作(java,c++用个map都很费劲)&br&4. 公司中,很大量的数据处理工作工作是不需要面对非常大的数据的&br&5. 巨大的数据不是语言所能解决的,需要处理数据的框架(hadoop, mpi。。。。)虽然小众,但是python还是有处理大数据的框架的,或者一些框架也支持python&br&6. 编码问题处理起来太太太方便了&br&&br&综上所述:&br&1. python可以处理大数据&br&2. python处理大数据不一定是最优的选择&br&3. python和其他语言(公司主推的方式)并行使用是非常不错的选择&br&4. 因为开发速度,你如果经常处理数据,而且喜欢linux终端,而且经常处理不大的数据(100m一下),最好还是学一下python&br&&br&&br&python数据处理的包:&br&1. 自带正则包, 文本处理足够了&br&2. cElementTree, lxml
默认的xml速度在数据量过大的情况下不足&br&3. beautifulsoup
处理html&br&4. hadoop(可以用python) 并行处理,支持python写的map reduce,足够了, 顺便说一下阿里巴巴的odps,和hadoop一样的东西,支持python写的udf,嵌入到sql语句中&br&5. numpy, scipy, scikit-learn 数值计算,数据挖掘&br&6. dpark(搬楼上的答案)类似hadoop一样的东西&br&&br&1,2,3,5是处理文本数据的利器(python不就处理文本数据方便嘛),4,6是并行计算的框架(大数据处理的效率在于良好的分布计算逻辑,而不是什么语言)&br&暂时就这些,最好说一个方向,否则不知道处理什么样的数据也不好推荐包,所以没有头绪从哪里开始介绍这些包
我很喜欢用python,用python处理数据是家常便饭,从事的工作涉及nlp,算法,推荐,数据挖掘,数据清洗,数据量级从几十k到几T不等,我来说说吧 百万级别数据是小数据,python处理起来不成问题,python处理数据还是有些问题的 Python处理大数据的劣势: 1. p…
開箱即用。
開箱即用。
自然是会的,判断都要进行计算。如果分支实在太多,有一种方法是把值和对应的操作存在dict里面,比如说:&br&&div class=&highlight&&&pre&&code class=&language-python&&&span class=&k&&if&/span& &span class=&n&&a&/span& &span class=&o&&==&/span& &span class=&mi&&1&/span&&span class=&p&&:&/span&
&span class=&k&&return&/span& &span class=&mi&&12&/span&
&span class=&k&&elif&/span& &span class=&n&&a&/span& &span class=&o&&==&/span& &span class=&mi&&2&/span&&span class=&p&&:&/span&
&span class=&k&&return&/span& &span class=&mi&&23&/span&
&span class=&k&&else&/span&&span class=&p&&:&/span&
&span class=&k&&return&/span& &span class=&mi&&19&/span&
&/code&&/pre&&/div&可以改写为:&br&&div class=&highlight&&&pre&&code class=&language-text&&map = {1:12, 2:23}
return map.get(a, 19)
&/code&&/pre&&/div&当分支很少的时候可能反而会变慢,因为dict的操作常数比较大,但是这样有几个好处,首先分支非常多的时候会更快,而且把hardcode的分支改成了数据结构,就可以动态添加、删除,可以很容易将硬分支改成OOP控制的可扩展的结构。最终还是看你的需求的。
自然是会的,判断都要进行计算。如果分支实在太多,有一种方法是把值和对应的操作存在dict里面,比如说: if a == 1:
elif a == 2:
可以改写为: map = {1:12, 2:23}
return map.get(a, 19)
当分支很少的时候可能反…
&img src=&/29cace866c357f8afce281bfacee734b_b.png& data-rawwidth=&440& data-rawheight=&792& class=&origin_image zh-lightbox-thumb& width=&440& data-original=&/29cace866c357f8afce281bfacee734b_r.png&&
这主要体现的是语言设计者的品味。Taste。其实想怎么设计只要能自圆其说都OK。Java、Python的风格都说得过去。&br&&br&从应用层面的角度看,确实就如 &a data-hash=&8fcc30baa5ee8e& href=&///people/8fcc30baa5ee8e& class=&member_mention& data-editable=&true& data-title=&@Coldwings& data-hovercard=&p$b$8fcc30baa5ee8e&&@Coldwings&/a& 所说,Python的写法允许用户给成员函数的第一个参数任意命名,常规命名是“self”,但想写成“this”啊啥的都可以。而Java则是在语言层面采用了隐含参数的设计,强制给成员方法安了个隐藏参数,固定名字为“this”。&br&&br&从VM设计的角度说,其实在这块CPython的字节码设计和JVM的字节码设计是颇为相似的。两者都通过操作数栈来传递参数。这里 &a data-hash=&8fcc30baa5ee8e& href=&///people/8fcc30baa5ee8e& class=&member_mention& data-editable=&true& data-title=&@Coldwings& data-hovercard=&p$b$8fcc30baa5ee8e&&@Coldwings&/a& 的答案就是错误的——CPython并不是“Py的参数传递其实是只压一个tuple,于是乎解包这个tuple所用的参数表就要直接列出来了”,而是跟Java一样一个个参数压入操作数栈,然后把这个栈顶的指定部分传给被调用函数。&br&在JVM规范里,这个栈叫做operand stack;在HotSpot JVM这个具体的JVM实现中,这个栈在解释器里叫做expression stack;在CPython实现中,这个栈叫做value stack。&br&&br&举个简单的例子:&br&&div class=&highlight&&&pre&&code class=&language-pycon&&&span class=&go&&$ python&/span&
&span class=&go&&Python 2.7.5 (default, Mar
9 :05) &/span&
&span class=&go&&[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin&/span&
&span class=&go&&Type &help&, &copyright&, &credits& or &license& for more information.&/span&
&span class=&gp&&&&& &/span&&span class=&k&&class&/span& &span class=&nc&&Foo&/span&&span class=&p&&(&/span&&span class=&nb&&object&/span&&span class=&p&&):&/span&
&span class=&gp&&... &/span&
&span class=&k&&def&/span& &span class=&nf&&bar&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&,&/span& &span class=&n&&x&/span&&span class=&p&&,&/span& &span class=&n&&y&/span&&span class=&p&&):&/span&
&span class=&gp&&... &/span&
&span class=&k&&return&/span& &span class=&n&&x&/span& &span class=&o&&+&/span& &span class=&n&&y&/span&
&span class=&gp&&... &/span&
&span class=&gp&&&&& &/span&&span class=&k&&def&/span& &span class=&nf&&call_foobar&/span&&span class=&p&&(&/span&&span class=&n&&foo&/span&&span class=&p&&,&/span& &span class=&n&&x&/span&&span class=&p&&,&/span& &span class=&n&&y&/span&&span class=&p&&):&/span&
&span class=&gp&&... &/span&
&span class=&k&&return&/span& &span class=&n&&foo&/span&&span class=&o&&.&/span&&span class=&n&&bar&/span&&span class=&p&&(&/span&&span class=&n&&x&/span&&span class=&p&&,&/span& &span class=&n&&y&/span&&span class=&p&&)&/span&
&span class=&gp&&... &/span&
&span class=&gp&&&&& &/span&&span class=&k&&def&/span& &span class=&nf&&call_call_foobar&/span&&span class=&p&&(&/span&&span class=&n&&x&/span&&span class=&p&&,&/span& &span class=&n&&y&/span&&span class=&p&&):&/span&
&span class=&gp&&... &/span&
&span class=&n&&f&/span& &span class=&o&&=&/span& &span class=&n&&Foo&/span&&span class=&p&&()&/span&
&span class=&gp&&... &/span&
&span class=&k&&return&/span& &span class=&n&&call_foobar&/span&&span class=&p&&(&/span&&span class=&n&&f&/span&&span class=&p&&,&/span& &span class=&n&&x&/span&&span class=&p&&,&/span& &span class=&n&&y&/span&&span class=&p&&)&/span&
&span class=&gp&&... &/span&
&span class=&gp&&&&& &/span&&span class=&kn&&import&/span& &span class=&nn&&dis&/span&
&span class=&gp&&&&& &/span&&span class=&n&&dis&/span&&span class=&o&&.&/span&&span class=&n&&dis&/span&&span class=&p&&(&/span&&span class=&n&&call_call_foobar&/span&&span class=&p&&)&/span&
&span class=&go&&
0 LOAD_GLOBAL
0 (Foo)&/span&
&span class=&go&&
3 CALL_FUNCTION
&span class=&go&&
6 STORE_FAST
2 (f)&/span&
&span class=&go&&
9 LOAD_GLOBAL
1 (call_foobar)&/span&
&span class=&go&&
12 LOAD_FAST
2 (f)&/span&
&span class=&go&&
15 LOAD_FAST
0 (x)&/span&
&span class=&go&&
18 LOAD_FAST
1 (y)&/span&
&span class=&go&&
21 CALL_FUNCTION
&span class=&go&&
24 RETURN_VALUE
&span class=&gp&&&&& &/span&&span class=&n&&dis&/span&&span class=&o&&.&/span&&span class=&n&&dis&/span&&span class=&p&&(&/span&&span class=&n&&call_foobar&/span&&span class=&p&&)&/span&
&span class=&go&&
0 LOAD_FAST
0 (foo)&/span&
&span class=&go&&
3 LOAD_ATTR
0 (bar)&/span&
&span class=&go&&
6 LOAD_FAST
1 (x)&/span&
&span class=&go&&
9 LOAD_FAST
2 (y)&/span&
&span class=&go&&
12 CALL_FUNCTION
&span class=&go&&
15 RETURN_VALUE&/span&
&/code&&/pre&&/div&看看CPython 2.7系列里,调用一个全局函数和调用一个成员函数,从调用方的角度看是什么样的。&br&call_call_foobar()里面有对全局函数call_foobar()的调用,而call_foobar()里有对成员函数Foo.bar()的调用。可见它们都是通过一系列LOAD_*指令(意思就是读出指定的内容并压到value stack上)来传递参数的。&br&&br&肯定会有同学问:Python支持多种参数:positional、keyword/default和rest arguments。难道调用函数的时候,调用方传递这几种参数都是用完全一样的方式?&br&&br&答案是肯定的,只要调用方用同样的语法传递参数,对应的CPython字节码传递参数的方式就是一样的。调用方传参数的语法(例如说是用普通的参数语法还是**语法)会影响调用函数用CALL_FUNCTION、CALL_FUNCTION_KW还是CALL_FUNCTION_EX之类的哪个字节码,但是只要是同一个语法就会对应一样的字节码,无论目标函数是如何声明的,调用方都是一样。&br&这是因为Python的函数调用是完全动态的——一个名字到底引用的是哪个函数实现,只有在调用的时候才可以知道。而目标函数是如何声明参数的,只有在实际调用时决议(resolve)出了目标函数是哪个才可以从目标函数得知。&br&所以在CPython的解释器实现中,函数调用有复杂的参数传递过程,要检查目标函数有多少个、哪些形式的参数,看情况逐个拷贝到合适的位置上(中间还可能需要创建新的dict来持有**kwarg形式的参数、创建新的tuple来持有*args形式的参数);甚至还要看目标函数是否需要捕获闭包,如果要的话还要处理这部分,然后才进入目标函数的函数体中。&br&&br&这种动态性加上复杂的参数传递过程,是影响CPython性能的因素之一。所以,在一个性能更好的实现中,函数的调用点需要尽可能地“静态化”——要能从调用方直接知道目标函数是哪个,并提取出目标函数的各种特性出来,把调用方传递参数的代码特化好,这样就可以避免每次函数调用就经过这种漫长的决议——查询特性——参数传递的过程。&br&例如说Pyston的inline cache就有潜力较好地将函数调用点静态化,大幅降低函数调用开销。&br&&br&呃,扯远了。
这主要体现的是语言设计者的品味。Taste。其实想怎么设计只要能自圆其说都OK。Java、Python的风格都说得过去。 从应用层面的角度看,确实就如
所说,Python的写法允许用户给成员函数的第一个参数任意命名,常规命名是“self”,但想写成“this”…
Python在这方面的package非常齐全:&br&&br&网页爬虫: scrapy(不太清楚)&br&数据挖掘: numpy, scipy, matplotlib, pandas(头三个是业界标准,第四个模拟R)&br&机器学习: scikit-learn, libsvm(极好)&br&自然语言处理: nltk(极好)
Python在这方面的package非常齐全: 网页爬虫: scrapy(不太清楚) 数据挖掘: numpy, scipy, matplotlib, pandas(头三个是业界标准,第四个模拟R) 机器学习: scikit-learn, libsvm(极好) 自然语言处理: nltk(极好)
不知道你的具体需求是什么,如果只是入门,我的经历或许对你有益。&br&我刚好自学过,就在前些天。&ol&&li&我用7天时间自学了Python,教材是:&a href=&///?target=http%3A//learnpythonthehardway.org/book/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&learnpythonthehardway.org&/span&&span class=&invisible&&/book/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a& 中文版:&a href=&///?target=http%3A//readthedocs.org/docs/learn-python-the-hard-way-zh_cn-translation/en/latest/index.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&readthedocs.org/docs/le&/span&&span class=&invisible&&arn-python-the-hard-way-zh_cn-translation/en/latest/index.html&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&/li&&li&然后用6天时间自学了Django,教材是:&a href=&///?target=http%3A///en/2.0/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&/en/2.0/&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a& 中文版:&a href=&///?target=http%3A///2.0/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/2.0/&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&&/li&&li&然后用14天时间开发出了我的帮人实现梦想的网站&a href=&///?target=http%3A//www.sunflr.me/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&sunflr.me/&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&。因为刚入门,估计代码质量很差。开发的时候,主要看的是:&a href=&///?target=https%3A///en/1.3/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/&/span&&span class=&invisible&&en/1.3/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&,倒没怎么看Python的网站。&br&&/li&&li&网站开发完上线,我用了2、3天时间,才弄上亚马逊的EC2服务器。因为没弄过Linux, Apache, Bitnami的DjangoStack, 期间几次想死的心都有了,如何上传文件就搞了1天多。其实有点经验的,20分钟估计就够了。&br&&/li&&/ol&
不知道你的具体需求是什么,如果只是入门,我的经历或许对你有益。 我刚好自学过,就在前些天。我用7天时间自学了Python,教材是: 中文版: 然后用6天时间自学了Django,教材是: 中文版:…
忍不住了,那个灵剑的python码农,之前也在黑php的问题下看你瞎回答。黑php没问题我也常常黑,可是你的关于php回答简直不懂装懂还瞎说,这里把你的回答一句一句。&br&&br&1、”多线程支持特别差只是其中之一。”这么说吧,php、ruby、python等这些比较主流的脚本语言里面论多线程支持,php是做得最好的。py和ruby支持多线程偷工减料加全局锁弄了个假的多线程,php本身改造了语言核心分了线程安全和非线程安全版本,php的多线程是真的多线程。其实脚本语言作为高级语言多线程并不鲁棒所以我基本不用多线程特性,要用多线程任务我还是倾向于用java/c++静态类型语言。&br&2、“比如说不区分字节流、多字节字符串、unicode字符串,需要在PHP文件里面同时写unicode、utf-8、gbk字符串的时候必须全部用16进制转义,这是一种怎样的令人崩溃的体验”。用python没被编码灾难的恶心过的有几个?我用php基本没有为编码问题操心过。你说为毛不用py3?是啊,py3傻逼的不兼容py2给第三方库社区带来了多大的麻烦,ubuntu16.04才敢升py3的吧,对不起大部分的生产环境centos6还py2.7呢。&br&3、“比如说多返回值,Python可以返回元组然后用简单的语法(a,b = my_func())将元组内容还原到不同变量,PHP只能返回数组,然后写好几行很丑的代码。”php不只能返回数组,还能返回对象等等,不过我相信你的意思是php没有py那样的语法糖。语法糖这东西我不是很care,也是用的时候才去查,你说的这个特性php里似乎有:$my_array = array(&Dog&,&Cat&,&Horse&);list($a, $b, $c) = $my_不过这根本不重要。&br&4、“PHP能续命到今天主要因为第一能调C的模块,所以依靠C程序员一步一步续上来,swoole也是这样;”php把cpu密集型函数写成c模块就是为了性能啊,这有啥可黑的?php7最棒的特性也是在尽量兼容的前提下提升性能:&a href=&///?target=https%3A///rs/zendtechnologies/images/PHP7-Performance%2520Infographic.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/rs/zendt&/span&&span class=&invisible&&echnologies/images/PHP7-Performance%20Infographic.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&。就我的判断而言,php语言和社区发展很好。&br&5、“第二因为PHP程序员普遍素质比较低,写代码的需求范围很狭窄,所以从来没碰到过这个语言的硬边界。基本上去写一两次Python,你就不会再想重新用回PHP了。”你这样地图炮是不对的,每个语言都有每个语言的使用场景,我原来写py挺多的,但是web相关的我觉得php更好用。&br&6、“等什么时候有人用纯PHP写出了OpenStack这样的云计算管理平台,Flask这样的小巧精致的Web框架,Scrapy这样的简单好用的爬虫框架,甚至哪怕是requests这样的HTTP客户端而不是到今天都还在拖着libcurl凑合着用,我们再来谈PHP不能做到什么。”OpenStack没用过不便评价,Flask这边组里一直在用在遇到性能问题后重构转java了,Scapy和requests你张口就来我今天就用这个2打你脸。Scrapy作为一个爬虫框架基本上写几个配置文件就可以跑了,但是爬虫的本质是开一个httpclient取回html+dom操作抽取数据,Scrapy封装的很厉害适合初学者改几个参数就跑起来了,但是扩展特别差。这边搞爬虫的py码农在要完成需要特别定制的爬虫都是直接开requests回来beautifulsoup抽数据的。requests这个httpclient是挺好用的,php的httpclient也并不只有libcurl,比较大的库的话guzzle也很好用,而且有很棒的异步支持。我用guzzle可以使用libevent的事件库单进程只开一个guzzle的httpclient并发同时异步爬100个网站,而requests并没有异步支持。&br&&br&我说这么多就是想,以上&br&&br&&br&&br&-------------------------------------------------&br&看了&a class=&internal& href=&/people/coldwings&&Coldwings&/a&的针对我的比较有水平的回答,我兴致顿时来了,这里回应如下:&br&&br&1、关于编码问题我相信已经讨论的足够清楚了,我觉得你说的也有道理,感性的东西这里就不回应了。&br&2、py下的异步并发方案我之前调研过很久的,grequests(GitHub - kennethreitz/grequests: Requests + Gevent = &3)是对gevent的很薄的包装,star很多但代码150行不到,实际上不怎么好用。&br&3、协程本质上是把异步用同步的方式来写,所以协程并不是说在并发上比异步强。&br&4、并不是只有Scrapy能调度phantomjs(你可以把phantomjs集成到任何爬虫里面),实际上我有在php下并发驱动phantomjs的一些经验(单机i7并发驱动80个phantomjs实例,包括并发下缓存、代理、资源泄漏和headless开发困难等各种坑的对应处理),我相信用py来驱动phantomjs也差不多,看你用啥顺手。&br&5、爬虫这块你所谓的分布式是指多机并发爬取的话,我用redis比较多,当然了我机器不多。我自己用php写了基于redis的多节点并发爬虫方案,有个爬虫2台PC并发最多150个phantomjs+150个guzzle的httpclient吧。多爬虫协作和任务分发啥的,比起专门的消息队列我比较推荐redis,因为redis的单机10w的qps在满足爬虫并发的同时,还有非常好用的5种数据结构,对爬虫的调度、状态查看、参数动态设置都有很大帮助。&br&6、我爬虫并发100是http并发不是tcp并发,我用php在单进程单httpclient下在低cpu低内存下异步并发跑满了小水管。线程池方案和异步并发方案优劣我认为已经讨论的足够清楚了(另外我真的觉得我的基于guzzle的单httpclient异步多并发的爬虫方案很不错的诶,我对这个很自满的。如果你感兴趣的话可以看看我的两篇博客讨论的这个问题:&a href=&///?target=http%3A///%3Fp%3D40& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&谈谈爬虫的并发问题&i class=&icon-external&&&/i&&/a&和&a href=&///?target=http%3A///%3Fp%3D423& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&redis使用心得+高并发httpclient的理解&i class=&icon-external&&&/i&&/a&)。&br&7、python的并发http方案我也之前也调查过(&a href=&///?target=https%3A///questions/2632520/what-is-the-fastest-way-to-send-100-000-http-requests-in-python& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&What is the fastest way to send 100,000 HTTP requests in Python?&i class=&icon-external&&&/i&&/a&),里面也有你提到的grequests和tornado的那个异步httpclient。tornado的那个异步的httpclient恰恰是基于libcurl的(&a href=&///?target=http%3A//www.tornadoweb.org/en/stable/httpclient.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&tornado.httpclient&i class=&icon-external&&&/i&&/a&)而且没有并发支持的,而php的guzzle默认是libcurl但是你可以选择别的事件库比如libevent的,guzzle可是支持异步并发的哦(在py和java下我找了一段时间都没找到这样的httpclient的)。&br&&br&最后说明一下,我只是看到灵剑那个python码农黑php真的是每一句话都是错的(从他之前的回答里也看出对php的偏见太大了,而且他根本不了解php,这样误导别人真的让人火大),实在受不了才跳出来打的。我相信每种语言都有它最适合的场景,也完全享受和别人交流一些技术上的东西的。
忍不住了,那个灵剑的python码农,之前也在黑php的问题下看你瞎回答。黑php没问题我也常常黑,可是你的关于php回答简直不懂装懂还瞎说,这里把你的回答一句一句。 1、”多线程支持特别差只是其中之一。”这么说吧,php、ruby、python等这些比较主流的脚本语…
有了xlwings,excel就成了个gui了,结合numpy,pandas各种爽。&br&还有比如直接插入matplotlib图表,比如利用python自带的sort一行代码完成vba写个几十行大一百行才能完成的复杂排序。&br&&br&刚看了下新版api,又有新的黑科技了,可以excel装个插件然后用python来写自定义公式
有了xlwings,excel就成了个gui了,结合numpy,pandas各种爽。 还有比如直接插入matplotlib图表,比如利用python自带的sort一行代码完成vba写个几十行大一百行才能完成的复杂排序。 刚看了下新版api,又有新的黑科技了,可以excel装个插件然后用python来写…
1. doc&br&2. run 看 log,strace/ltrace 看进程相关调用&br&3. 硬读源码,怕忘记各种调用关系,就拿笔在白纸上画流程,复杂的直接上 yEd&br&4. 关键过程上 pdb debug&br&5. use it,这步最关键,不常用都白搭&br&&br&黑盒白盒都上了,就是这样的姿势。
1. doc 2. run 看 log,strace/ltrace 看进程相关调用 3. 硬读源码,怕忘记各种调用关系,就拿笔在白纸上画流程,复杂的直接上 yEd 4. 关键过程上 pdb debug 5. use it,这步最关键,不常用都白搭 黑盒白盒都上了,就是这样的姿势。
第一次被邀请来装逼,好吧,我就试着装一个:&br&&a class=&video-box& href=&///?target=http%3A///v_show/id_XMTUzMTk2NjgyOA%3D%3D.html& target=&_blank& data-video-id=&& data-video-playable=&& data-name=&ev3 robot—在线播放—优酷网,视频高清在线观看& data-poster=&/CA& data-lens-id=&&&
&img class=&thumbnail& src=&/CA&&&span class=&content&&
&span class=&title&&ev3 robot—在线播放—优酷网,视频高清在线观看&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&/v_show/id_XMTUzMTk2NjgyOA==.html&/span&
&/a&&br&乐高机器人,刷完Debian Linux,然后用Python3开发的程序。&br&如果你赶脚装得还不错,现在学完 &a href=&///?target=http%3A///wiki/958fa6d3a2e542c000& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Python教程 - 廖雪峰的官方网站&i class=&icon-external&&&/i&&/a& 再装还来得及。
第一次被邀请来装逼,好吧,我就试着装一个: 乐高机器人,刷完Debian Linux,然后用Python3开发的程序。 如果你赶脚装得还不错,现在学完
再装还来得及。
&b&各位爱学习的朋友,非常抱歉,我没有坚持下去,中间发生了很多意料之外的事,历经了大半年的颓废期,在我整个人的状态调整之后,我还会将编程学习慢慢捡起来的,因为它始终让我充满好奇!祝你们所有人成功!&/b&&b&&br&&br&&br&&br&&br&&br&自学编程前&/b&&br&(1)基础:本科专业有开设C语言这门课程,貌似选修,不过现在也忘了,唯一记得的是,这门课程靠背题的方式考了95+。与此同时,在刚上大学时,就被外面培训班的宣传及室友们“好学的热情”给“误导”进了有关国家计算机网络技术三级的培训班,然而,我基本没去过,理所当然,考试也没参加。后来的两年,看着室友们都陆续取得了国三证书,想着自己报培训班的钱不能白花,也就下定决心通过“自学+请教”的方式学习C语言,之后顺利通过考试取得证书。以上就是我所有的编程基础,或许知乎面前不自信的你会说:“你这是算有基础吧”,我的回答是:“我心里清楚自己大学是怎么度过的,你说有就有吧,我认为是零,因为脑子里只有i++,但i++和++i到底是谁先加1,我现在已不确定。”&br&(2)年龄和时间:关于大多数人说到年龄大和时间少的问题,我想通过以下两个反问作答。马上就要硕士毕业了,我年龄还会小吗?六月份就要毕业了,身边的同学都在陆续找工作了,父母验收投资教育回报的时候快到了,给我静心学编程的时间还多吗?&br&(3)方向选定:在这里我要提前声明一下,因为自己不清楚编程界的术语,在表达专业术语时可能会显得很业余或是驴唇不对马嘴,还请见谅!目前我知道的就是以下这些:语言类(C、C#、C++、Java、Javascript、Python、Html5)、框架(CSS?、Django)、数据库(MySQL、ORACLE、SQL-Sever)和系统(Linux、Windows、Macintosh、Android、iOS),因此,在选方向的问题上我也是很茫然的。不过,通过之前逛知乎的积累,我大概知道Html5和Python学起来会相对要简单些,Python做爬虫和数据分析会有优势,而爬虫大多是在网页中进行,同时Django(目前还没见过这哥们长啥样)是与Python有关的框架,也知道Html需要搭档CSS(这哥们我也木有见过)、Javascript和数据库,所以我目前的方向大概就是学Python、Html5、CSS、Javascript、MySQL和Django。我是否理解错了呢?以后是否会再做调整呢?我也不清楚,我想或许在学习的过程中,我自然而然就会知道该做怎样的调整吧,现在我能做的就是用心去学。PS:望有经验的前辈们能够及时批评指正,来促进并见证我的成长,三人行必有我师!&br&(4)学习方式与计划:打算通过搜索网络视频或文本资源的方式来自学,这里或许有人会问,为什么不去培训机构?这个我也打听过了,貌似也是集中看视频学习吧,何况还要花昂贵的学费,后来想想就算了,只要自制力强且有决心,我想自己也能通过网络资源完成自学,实在有困难,就把去培训班当下下策。关于学习计划的事,说实话我没有明确的计划,因为对所要学习内容的深度与广度还一无所知,只是要求自己先学Python,等到自认为学到还可以的时候再去学Html5,往后则根据情况作调整。另外,要求每天一有时间就全心投入到学习当中,通过看一遍练一遍的方式走完每个课程。&br&(5)关于学习感受:在接下来几个月的自学过程中,我每个星期都会抽出时间来记录,其中包含自己心态、情绪的变化,遇到的挫折、困难及解决方法。&br&小结:上述一大堆文字主要是描述我自学编程前的情况以及是怎么开始准备学习编程的,如果大家还想知道一些什么可以提出,我会结合该问题的出发点,作选择性的回答。在以上或接下来文字记录过程中,若有表达不当的地方,还麻烦大家帮我提出来,我会校正。&br&&b& 记于.20:32&/b&&br&&b&
自学编程中&/b&&br&更新一:&br&从4.5号到今天,学完了Python基础,目前感觉还行~&br&(1)学习方法:在网上找了一个Python基础视频教程(总共34节课)就跟着开始学习,这次的学习方法:采用“听课+思考+不做笔记+不练习”的方式一直往下听;直到某一节课听起来感觉吃力了,再返回进行第二遍学习,采用“快进听课+做笔记+思考+练习”的方式巩固知识,编程笔记于当晚温习一遍,编程练习于睡前默想一遍;在第二遍学习之后,前面的知识基本就吸收的差不多了,再接着从上次吃力的那一节课按之前的方法循环,如此下来,整个课程就这样学完了。最后,也就是昨天一天,我又把笔记和练习重新整理,归纳成一个系统、清晰的知识库了,总共归纳出了59个知识要点。ps:本想把笔记附上,想想太占位置,就幻想了一下,或许若干天之后,可以把笔记放在自己建的网站上,希望能为初学者尽一点绵薄之力。&br&(2)学习内容:在基础学习中,主要掌握:(a)类似格式转化、转义字符、熟悉开发工具等细节上的基础知识;(b)if语句、while循环、for循环及其迭代器原理;(c)string及list的属性、通用操作及主要s.function()和list.function();(d)实参、形参、返回值的函数自定义def function():;(e)文件的.open()、.read()、.write()、.close()操作;(f)几个小编程(刷网页浏览次数、去除字符串中的空格用来分别生成连续字符、字符通用替换)、实现内部函数split()、文件格式化写入)。&br&(3)遇到难点:(a)我现在用的是Python2.7,在使用过程中,IDLE特别容易出现“闪退”现象,即在保存代码准备运行时,它会弹出确认保存的对话框,点击一次确认保存,它又会弹出一次,再循环点击确认两次,之后就闪退了,卸载、安装重复了几次,问题还是解决不了,请问这是什么原因?难道是Python的集成开发环境本来就不稳定?(b)httplib2安装包哪里有下载?除了收费的就是没用的,有哪位好心人能分享一下?PS:以上两个问题希望有能者帮忙解决一下。&br&(4)情绪、心态:(a)本周面临的诱惑无非是工作的问题,因为要毕业了,之前投过简历,过程中也陆续收到面试邀请,前几天决心学代码,所以基本上都铁了心的给予拒绝,唯一一份纠结的是关于本月26号的面试,有过思想上的挣扎,因为那份工作的薪资待遇很诱人,但这次的“二面”还需要花一些时间去准备,尤其是英语口语,并且路程遥远,考虑到现在时间紧迫且已经下定决心改行,在这几天的一番挣扎之后,还是决心不去了。(b)学习Python的心态上,其中有遇到过理解不了的地方,第二遍学习之后基本都解决了,也就是说目前心态良好,仍对更高阶的Python知识保持渴望心理。&br&(5)下一步计划:有知友给我提了些建议,在此好心谢过,我也特别想兼顾学习HTML5及相关知识,但还是克制住了,知识是需要慢慢积累的,不能抱着一口吃成胖子的心态学习,所以接下来应该压制住亢奋,继续学习中阶Python知识。&br&&b&
记于.11:38&/b&&br&这一个多星期的学习,貌似给自己“打脸”了,待我详细讲述:&br&(1)学习内容:因为之前把Python基础学完了,后来想找个中阶教程跟着学,但无奈没找到好的资源,也碰巧找到了一个更好的免费学习的网站,由于当前教程与之前所学的教程还有一定区别,又把这个新的Python基础教学视频重新听了一遍,感觉甚好。在使用过程中,无奈看到该网站有个前端工程师学习计划,仔细一看发现Python不在计划之中,于是把Python暂时放下了,重新开始按照这个计划学习,首先学习了Html5和Css,也就是说这些天一直都在自学这些内容(打脸),目前已经基本掌握了,按照计划,接下来的时间开始准备学习Js和Jquery。&br&(2)学习难点:Html5和Css还是比较容易学习的,唯一要注意的是:写代码过程一定要养成良好的书写习惯以及在页面布局过程思路必须清楚,div和css类定义在关联上特别容易写迷糊,这些都是我常犯糊涂的地方。&br&(3)情绪、心态:因为即将毕业,最近个人和班里的事务都比较繁杂,需要时不时的抽出时间来处理,进而学习效率不是很高;另外,也意识到自己身上开始显现一些负能量了,目前在做积极调整,拟打算开始“夜跑”,锻炼身体。最后,我想对自己说“抛弃杂念,继续加油”!也想对自学的你们说“我们在做好一件事情的过程中,负能量会成为生活的常态,能否及时并勇于化解负能量决定着我们能否把这件事做成功。”&br&&b&记于.19:07&/b&&b&&br&本次就更新到这了,以后的学习可能会更难,更新时间间隔或许会变长些,上述有讲到不详细的地方还请指出,希望能得到前辈的指引,也希望能与当下在自学的你们共勉,加油!&/b&
各位爱学习的朋友,非常抱歉,我没有坚持下去,中间发生了很多意料之外的事,历经了大半年的颓废期,在我整个人的状态调整之后,我还会将编程学习慢慢捡起来的,因为它始终让我充满好奇!祝你们所有人成功! 自学编程前 (1)基础:本科专业有开设C语言这门…
&p&1.找一个简单易懂的入门教程来学习!&/p&&p&&a href=&///?target=http%3A///course/python/276-2604/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Python编程的介绍&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&///?target=http%3A///course/python/393-4373/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Python教程学习前言-Python开发&i class=&icon-external&&&/i&&/a&&br&&/p&&p&推荐使用google搜索相关课程以及源码。&br&
2.找一个项目实践,也可以跟着你看的教程来实践操作!网上一搜有一大把这样的教程以及源码。&/p&&p&&a href=&///?target=http%3A///course/python/460-5879/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&项目介绍及演示&i class=&icon-external&&&/i&&/a&&br&&/p&&p&&a href=&///?target=http%3A///course/python/457-5793/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GUI类库设计架构-Tkinter架构分析&i class=&icon-external&&&/i&&/a&&br&
3最好能够找一个Python的老师带着你学!这个方法其实挺多的,加群找人,不懂得就问。&/p&&p&推荐配套课程:&a href=&///?target=http%3A///course/python/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Python视频教程_Python开发实战视频&i class=&icon-external&&&/i&&/a&&/p&&p&推荐的在线coding:&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LeetCode Online Judge&i class=&icon-external&&&/i&&/a&&/p&
1.找一个简单易懂的入门教程来学习! 推荐使用google搜索相关课程以及源码。
2.找一个项目实践,也可以跟着你看的教程来实践操作!网上一搜有一大把这样的教程以及源码。
我们目前正在开发的回测引擎使用的也是python,近期也在进行性能方面的优化,以下建议供参考:&br&&br&1. 在动手优化之前,先profile看看,程序时间都花在哪些地方了:&br&&div class=&highlight&&&pre&&code class=&language-text&&python -m cProfile -o output.prof your_program
&/code&&/pre&&/div&跑完之后,会生成一个output.profile文件。接下来需要对这个文件进行分析,这方面的工具我推荐&a href=&///?target=https%3A//jiffyclub.github.io/snakeviz/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&SnakeViz&i class=&icon-external&&&/i&&/a&,神器。安装非常简单,pip install snakeviz 即可。&br&&div class=&highlight&&&pre&&code class=&language-text&&snakeviz output.prof
&/code&&/pre&&/div&运行之后,会打开一个浏览器窗口,好好看看,哪些函数耗时最多,耗时是因为调用次数太多呢,还是因为单次调用耗时长,明确优化重点;&br&&br&2. 减少重复计算,缓存计算结果。看看 functools.lru_cache。&br&&br&3. 能用list comprehension的地方,不要用for;能用numpy的地方,不要手写循环,不要用pandas;&br&&br&4. 看你的回测,40w个tick的话,数据量不算大,应该是直接load到内存里的吧?&br&&br&5. 还是慢的话,上&a href=&///?target=http%3A//numba.pydata.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Numba — Numba&i class=&icon-external&&&/i&&/a&,就是安装麻烦一些,使用起来非常方便,速度提高一两个数量级没问题;&br&&br&6. 如果你用的包PyPy都支持的话,试试pypy;&br&&br&7. Cython、c module,上面的都没效果的话,这个是最后的候选方案了。&br&&br&----------------&br&广告时间:&br&我们目前正在招人,欢迎各位投条:&br&&a href=&///?target=https%3A///jobs& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Ricequant - Beta&i class=&icon-external&&&/i&&/a&
我们目前正在开发的回测引擎使用的也是python,近期也在进行性能方面的优化,以下建议供参考: 1. 在动手优化之前,先profile看看,程序时间都花在哪些地方了: python -m cProfile -o output.prof your_program
跑完之后,会生成一个output.profile文件。接…
欢迎尝试我们thunlp组发布的THULAC中文词法分析工具包,包括中文分词和词性标注功能,目前包括C++、Python和Java版本。与各常用工具包的性能和效果比较可以参考:&a href=&///?target=http%3A//thulac.thunlp.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&THULAC:一个高效的中文词法分析工具包&i class=&icon-external&&&/i&&/a& 。
欢迎尝试我们thunlp组发布的THULAC中文词法分析工具包,包括中文分词和词性标注功能,目前包括C++、Python和Java版本。与各常用工具包的性能和效果比较可以参考: 。
正好最近在学习CGI。&br&&br&CGI是比较原始的开发动态网站的方式。你可以想象一下,一个网站的动态内容肯定是程序生成的,光是静态的html页面无法达到这个效果。那么,这个程序就需要接受客户端的请求,然后进行相应处理,再返回给客户端,客户端和服务端的通信当然是通过HTTP协议。&br&&br&然后我们会发现,这个程序在处理客户端请求的时候,大部分时候会进行很多重复的工作,比如说HTTP请求的解析。也就是说,你的程序需要解析HTTP请求,我的程序也需要解析。&br&&br&于是为了DRY原则,Web服务器诞生了。(以下所说的都是CGI的工作模式)&br&&br&于是Web服务器可以解析这个HTTP请求,然后把这个请求的各种参数写进进程的环境变量,比如&br&REQUEST_METHOD,PATH_INFO之类的。之后呢,服务器会调用相应的程序来处理这个请求,这个程序也就是我们所要写的CGI程序了。它会负责生成动态内容,然后返回给服务器,再由服务器转交给客户端。服务器和CGI程序之间通信,一般是通过进程的环境变量和管道。&br&&br&这样做虽然很清晰,但缺点就是每次有请求,服务器都会fork and exec,每次都会有一个新的进程产生,开销还是比较大的。&br&&br&原因在与CGI程序是一个独立的程序,它是可以独立运行的(在提供HTTP请求的情况下),它可以用几乎所有语言来写,包括perl,c,lua,python等等。所以对于一个程序,服务器只能以fork and exec的方式来调用它了。&br&&br&我所理解的CGI差不多就是这样。
正好最近在学习CGI。 CGI是比较原始的开发动态网站的方式。你可以想象一下,一个网站的动态内容肯定是程序生成的,光是静态的html页面无法达到这个效果。那么,这个程序就需要接受客户端的请求,然后进行相应处理,再返回给客户端,客户端和服务端的通信当…
&div class=&highlight&&&pre&&code class=&language-text&&#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
import time
import random
import sys
def get_post_data(url, headers):
# 访问一次网页,获取post需要的信息
'TAB_QuerySubmitSortData': '',
'TAB_RowButtonActionControl': '',
req = requests.get(url, headers=headers)
except Exception, e:
print 'get baseurl failed, try again!', e
sys.exit(1)
soup = BeautifulSoup(req.text, &html.parser&)
TAB_QueryConditionItem = soup.find(
'input', id=&TAB_QueryConditionItem270&).get('value')
# print TAB_QueryConditionItem
data['TAB_QueryConditionItem'] = TAB_QueryConditionItem
TAB_QuerySortItemList = soup.find(
'input', id=&TAB_QuerySort0&).get('value')
# print TAB_QuerySortItemList
data['TAB_QuerySortItemList'] = TAB_QuerySortItemList
data['TAB_QuerySubmitOrderData'] = TAB_QuerySortItemList
__EVENTVALIDATION = soup.find(
'input', id='__EVENTVALIDATION').get('value')
# print __EVENTVALIDATION
data['__EVENTVALIDATION'] = __EVENTVALIDATION
__VIEWSTATE = soup.find('input', id='__VIEWSTATE').get('value')
# print __VIEWSTATE
data['__VIEWSTATE'] = __VIEWSTATE
except Exception, e:
print 'get post data failed, try again!', e
sys.exit(1)
return data
def get_info(url, headers):
req = requests.get(url, headers=headers)
soup = BeautifulSoup(req.text, &html.parser&)
items = soup.find(
'table', id=&mainModuleContainer__ctl00_ctl00_p1_f1&)
# 所需信息组成字典
division = items.find(
'span', id=&mainModuleContainer__ctl00_ctl00_p1_f1_r1_c2_ctrl&).get_text().encode('utf-8')
info['XingZhengQu'] = division
# 项目位置
location = items.find(
'span', id=&mainModuleContainer__ctl00_ctl00_p1_f1_r16_c2_ctrl&).get_text().encode('utf-8')
info['XiangMuWeiZhi'] = location
# 面积(公顷)
square = items.find(
'span', id=&mainModuleContainer__ctl00_ctl00_p1_f1_r2_c2_ctrl&).get_text().encode('utf-8')
info['MianJi'] = square
# 土地用途
purpose = items.find(
'span', id=&mainModuleContainer__ctl00_ctl00_p1_f1_r3_c2_ctrl&).get_text().encode('utf-8')
info['TuDiYongTu'] = purpose
# 供地方式
source = items.find(
'span', id=&mainModuleContainer__ctl00_ctl00_p1_f1_r3_c4_ctrl&).get_text().encode('utf-8')
info['GongDiFangShi'] = source
# 成交价格(万元)
price = items.find(
'span', id=&mainModuleContainer__ctl00_ctl00_p1_f1_r20_c4_ctrl&).get_text().encode('utf-8')
info['ChengJiaoJiaGe'] = price
# print info
# 用唯一值的电子监管号当key, 所需信息当value的字典
all_info = {}
Key_ID = items.find(
'span', id=&mainModuleContainer__ctl00_ctl00_p1_f1_r1_c4_ctrl&).get_text().encode('utf-8')
all_info[Key_ID] = info
return all_info
def get_pages(baseurl, headers, post_data, date):
print 'date', date
# 补全post data
post_data['TAB_QuerySubmitConditionData'] = post_data[
'TAB_QueryConditionItem'] + ':' + date
while True:
page {0}'.format(page)
# 休息一下,防止被网页识别为爬虫机器人
time.sleep(random.random() * 3)
post_data['TAB_QuerySubmitPagerData'] = str(page)
req = requests.post(baseurl, data=post_data, headers=headers)
# print req
soup = BeautifulSoup(req.text, &html.parser&)
items = soup.find('table', id=&TAB_contentTable&).find_all(
'tr', onmouseover=True)
# print items
for item in items:
print item.find('td').get_text()
link = item.find('a')
print item.find('a').text
url = '/' + item.find('a').get('href')
print get_info(url, headers)
print 'no content, this ten days over'
if __name__ == &__main__&:
# time.time()
baseurl = '/default.aspx?tabid=263'
headers = {
'User-Agent': 'Mozilla/5.0 (M Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36',
'Host': ''
post_data = (get_post_data(baseurl, headers))
date = '~'
get_pages(baseurl, headers, post_data, date)
&/code&&/pre&&/div&&br&demo大概这个样子的,&br&1 :
这个页面每次最多显示20页,需要每10天当查询条件.我只做了一个10天的, 你可以用datatime库遍历所有的时间.&br&&br&2 :
先用requests.get访问一次网页,获取所需的post内容&br&&img src=&/2f61bd6ddabfab05033dfa0_b.jpg& data-rawwidth=&984& data-rawheight=&500& class=&origin_image zh-lightbox-thumb& width=&984& data-original=&/2f61bd6ddabfab05033dfa0_r.jpg&&&br&3: 具体每个土地页面返回一个用唯一数值的电子监管号当key, 所需数据当值的字典,&br&&br&4: 数据我没有存储, 只是打印出来,你可以根据所需的方式存储, 可以存到csv中, 存到mysql中.&br&&br&&img src=&/fb2e54c009cf5efd4b9593_b.jpg& data-rawwidth=&1406& data-rawheight=&566& class=&origin_image zh-lightbox-thumb& width=&1406& data-original=&/fb2e54c009cf5efd4b9593_r.jpg&&
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
import time
import random
import sys
def get_post_data(url, headers):
# 访问一次网页,获取post需要的信息
'TAB_QuerySubmitSortData': '…
已有帐号?
无法登录?
社交帐号登录}

我要回帖

更多关于 如何看待未来科技 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信