问题:干净,轻巧的替代Python的替代品吗?[关闭]
一个(很久以前),我写了一个网络蜘蛛,对它进行了多线程处理,以使并发请求能够同时发生。那是我的Python青年时代,在我了解GIL及其为多线程代码造成的相关麻烦之前(IE,大多数情况下,这些东西最终都被序列化了!)…
我想对这段代码进行重做,以使其更健壮并性能更好。基本上有两种方法可以执行此操作:我可以使用2.6+中的新多处理模块,也可以使用某种基于反应堆/事件的模型。我宁愿稍后再做,因为它更加简单且不易出错。
因此,问题与哪种框架最适合我的需求有关。以下是到目前为止我所知道的选项列表:
- Twisted:Python反应器框架的祖父:看起来很复杂,但是有点a肿。陡峭的学习曲线,可完成一项小任务。
- Eventlet:从在家伙lindenlab。基于Greenlet的框架,适用于此类任务。我看了一下代码,但看起来不是很漂亮:不符合pep8,散布着印刷品(为什么人们要在框架中这样做!?),API似乎有点不一致。
- PyEv:不成熟,尽管它基于libevent,所以现在似乎还没有人在使用它,因此它有一个可靠的后端。
- asyncore:来自stdlib:über低级,似乎涉及很多工作,只是为了使事情起步。
- 龙卷风:尽管这是一种面向服务器的产品,旨在为动态网站提供服务器,但它确实具有异步HTTP客户端和简单的ioloop。看起来可以完成工作,但不能达到预期目的。[编辑:不幸的是,它不能在Windows上运行,这对我来说算是它了-这是我支持这个la脚平台的要求]
我有什么想念的吗?当然,必须有一个适合简化异步网络库的最佳选择的库!
[编辑:非常感谢intgr指向此页面。如果滚动到底部,您将看到一个非常不错的项目列表,旨在以一种或多种方式解决此任务。实际上,自Twisted诞生以来,事情确实已经发生了变化:人们现在似乎更喜欢基于协同例程的解决方案,而不是传统的面向反应器/回调的解决方案。这种方法的好处是更直接的代码:我过去确实发现过,特别是在使用boost.asio时。在C ++中,基于回调的代码可能导致难以遵循的设计,并且对于未经训练的人来说是相对模糊的。使用协同例程可使您编写看起来至少同步一些的代码。我想现在我的任务是找出我喜欢的众多库中的哪一个,并尝试一下!很高兴我现在问…]
[编辑:可能是关注或偶然发现此问题或在某种意义上关心此主题的任何人所感兴趣的:我发现了该工作可用工具的当前状态非常出色的文章]
回答 0
我喜欢并发 Python模块,该模块依赖轻量级线程的Stackless Python微线程或Greenlets。所有阻塞网络I / O通过一个libevent
循环透明地实现异步,因此它的效率应与真正的异步服务器差不多。
我想它在这种方式上类似于Eventlet。
缺点是其API与Python的sockets
/ threading
模块完全不同;您需要重写您的应用程序的一部分(或编写一个兼容性填充层)
编辑:似乎也有cogen,这是相似的,但是使用Python 2.5的增强型生成器为其协程而不是Greenlets。这使得它比并发和其他替代方法更可移植。网络I / O直接通过epoll / kqueue / iocp完成。
回答 1
扭曲是复杂的,您是正确的。扭曲不肿。
如果您在此处查看:http : //twistedmatrix.com/trac/browser/trunk/twisted,您将找到一个组织良好,全面且经过良好测试的,包含许多 Internet协议的套件,以及编写的辅助代码并部署非常复杂的网络应用程序。我不会将膨胀与全面性混为一谈。
众所周知,Twisted文档乍一看并不是最用户友好的,并且我相信这会避免不幸的人们。但是如果您花时间的话,Twisted太棒了(IMHO)。我做到了,事实证明这是值得的,我建议其他人也可以尝试。
回答 2
在API方面,它遵循与标准库(尤其是线程和多处理模块)相同的约定(在这里有意义)。因此,您可以使用诸如Queue和Event之类的熟悉的东西。
它仅支持libevent(从1.0开始更新: libev)作为反应堆实现,但充分利用了它的优点,它具有基于libevent-http的快速WSGI服务器,并通过libevent-dns解决DNS查询,而不是像其他大多数库一样使用线程池做。(更新:由于使用1.0 c-ares进行异步DNS查询;线程池也是一种选择。)
与eventlet一样,它通过使用greenlets使得不需要回调和Deferreds 。
查看示例:并发下载多个URL,长时间轮询webchat。
回答 3
回答 4
这些解决方案都无法避免GIL阻止CPU并行的事实-它们只是获得线程已经具有的IO并行的更好方法。如果您认为可以做得更好的IO,则可以采取以下任何一种方法,但是如果瓶颈是处理结果,那么除了多处理模块之外,这里没有任何帮助。
回答 5
我不会说Twisted blo肿,但很难缠住你的头。我一直避免真正地学会学习,因为我一直希望对“小任务”更轻松一些。
但是,既然我已经使用了它,我不得不说所有的电池都非常好。
我使用过的所有其他异步库最终都没有看起来那么成熟。Twisted的事件循环很稳定。
我不太确定如何解决陡峭的Twisted学习曲线。如果有人将其分叉并清理一些东西,例如删除所有向后兼容的废纸and和无效项目,那可能会有所帮助。但这就是成熟软件的本质。
回答 6
回答 7
我开始在某些事情上使用扭曲。它的美丽几乎是因为它“ blo肿”。那里有几乎所有主要协议的连接器。您可以拥有一个jabber机器人,该机器人将接收命令并将其发布到irc服务器,将其通过电子邮件发送给某人,运行命令,从NNTP服务器读取以及监视网页中的更改。坏消息是它可以完成所有这些操作,并且会使诸如OP所述的简单任务变得过于复杂。python的优点是您只包含需要的内容。因此,尽管下载量可能是20mb,但您可能只包含2mb的库(仍然很多)。我最大的困惑是,尽管它们包含示例,但您只能依靠基本的tcp服务器。
虽然不是python解决方案,但最近我已经看到node.js获得了更多的吸引力。实际上,我已经考虑过将其用于较小的项目,但是当我听到javascript时我只是畏缩:)
回答 8
关于这一主题的一本好书是:Abe Fettig撰写的“ Twisted Network Programming Essentials”。这些示例说明了如何编写非常Pythonic的代码,对我个人而言,不要以strike肿的框架为基础。看书中的解决方案,如果它们不是干净的,那么我不知道干净意味着什么。
我唯一的困惑与其他框架(如Ruby)相同。我担心,它会扩大规模吗?我不愿意将客户端委托给将存在可伸缩性问题的框架。
回答 9
Whizzer是一个使用pyev的微型异步套接字框架。它的速度非常快,主要是因为pyev。它试图提供类似的界面,但略有改动。
回答 10
也可以尝试Syncless。它基于协程(因此类似于Concurrence,Eventlet和gevent)。它实现了socket.socket,socket.gethostbyname(等),ssl.SSLSocket,time.sleep和select.select的插入式非阻塞替换。它很快。它需要Stackless Python和libevent。它包含一个用C编写的强制性Python扩展(Pyrex / Cython)。
回答 11
我确认不同步的好处。它可以使用libev(libevent的更新,更干净,性能更好的版本)。有时它没有libevent所提供的支持,但是现在开发过程更进一步,非常有用。
回答 12
如果您只想要一个简化的,轻量级的HTTP请求库,那么我觉得Unirest真的很好
回答 13
欢迎您来看看PyWorks,它采用了完全不同的方法。它使对象实例在其自己的线程中运行,并对该对象进行异步函数调用。
只需让一个类从Task继承而不是从Object继承,它就异步了,所有方法调用都是Proxies。返回值(如果需要)是将来的代理。
res = obj.method( args )
# code continues here without waiting for method to finish
do_something_else( )
print "Result = %d" % res # Code will block here, if res not calculated yet
可以在http://bitbucket.org/raindog/pyworks上找到PyWorks。