哪个 Python 异步库最适合我的代码?异步?扭曲? [英] Which Python async library would be best suited for my code? Asyncore? Twisted?

查看:16
本文介绍了哪个 Python 异步库最适合我的代码?异步?扭曲?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个程序,它将同时从两个网络资源"中读取数据.我想尝试一种异步方法而不是使用线程.这让我想知道要使用哪个库...

I have a program I'm working on that will be reading from two 'network sources' simultaneously. I wanted to try out an asynchronous approach rather than use threading. This has lead me to wonder which library to use...

我想出了一些简单的示例代码来演示我的程序将要做什么:

I've come up with some simple example code that kind of demonstrates what my program will be doing:

import sniffer

def first():
    for station in sniffer.sniff_wifi():
        log(station.mac())

def second():
    for station in sniffer.sniff_ethernet():
        log(station.mac())

first()
second()

这两个 sniffer 方法看起来有点像这样:

The two sniffer methods look somewhat like this:

def sniff_wifi(self):

    while True:
        yield mac_address

while True 循环显然使它们阻塞.

The while True loop obviously makes them blocking.

我想为此使用 asyncore,因为它是标准库的一部分.没有第 3 方的依赖是额外的.但是,如果你推荐我这样做,这并不意味着我不会使用它...

I want to use asyncore for this as it is part of the standard library. No 3rd party dependencies are a bonus. However, that doesn't mean I won't use it if you recommend I do...

我可以用 asyncore 实现我想要做的事情吗?如果是这样,你能告诉我如何将我的示例代码转换为异步代码"吗?你知道任何好的异步教程吗?

Can I achieve what I'm trying to do with asyncore? If so, could you show me how to convert my example code to 'asyncore code'? Do you know of any good asyncore tutorials?

推荐答案

Twisted 在几乎所有可能的方面都更好.它更便携、更有特色、更简单、更可扩展、更好维护、更好记录,并且可以制作美味的煎蛋.就所有意图和目的而言,Asyncore 已过时.

Twisted is better in pretty much every possible way. It's more portable, more featureful, simpler, more scalable, better maintained, better documented, and it can make a delicious omelette. Asyncore is, for all intents and purposes, obsolete.

很难在简短的回答中展示 Twisted 的所有优势(我如何展示 http/dns/ssh/smtp/pop/imap/irc/xmpp/进程生成/多线程 服务器在一个简短的例子中?),所以我将专注于最常见的误解之一人们似乎对 Twisted 有一个看法:它在某种程度上比 asyncore 更复杂或更难使用.

It's hard to demonstrate all the ways in which Twisted is superior in a short answer (how could I demonstrate a http/dns/ssh/smtp/pop/imap/irc/xmpp/process-spawning/multi-threading server in a short example?), so instead I'll focus on one of the most common misconceptions that people seem to have about Twisted: that it's somehow more complex or harder to use than asyncore.

让我们从异步示例开始.为了避免有偏见的演示,我将使用一个仍然有点喜欢 asyncore 的其他人的例子.这是一个简单的异步示例 取自 Richard Jones 的博客(为简洁起见省略了注释).

Let's start with an asyncore example. In order to avoid a biased presentation, I'll use an example from someone else who still likes asyncore a bit. Here's a simple asyncore example taken from Richard Jones' weblog (with comments elided for brevity).

首先,这是服务器:

import asyncore, socket

class Server(asyncore.dispatcher):
    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.bind(('', port))
        self.listen(1)

    def handle_accept(self):
        socket, address = self.accept()
        print 'Connection by', address
        EchoHandler(socket)

class EchoHandler(asyncore.dispatcher_with_send):
    def handle_read(self):
        self.out_buffer = self.recv(1024)
        if not self.out_buffer:
            self.close()

s = Server('', 5007)
asyncore.loop()

这里是客户:

import asyncore, socket

class Client(asyncore.dispatcher_with_send):
    def __init__(self, host, port, message):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect((host, port))
        self.out_buffer = message

    def handle_close(self):
        self.close()

    def handle_read(self):
        print 'Received', self.recv(1024)
        self.close()

c = Client('', 5007, 'Hello, world')
asyncore.loop()

有一些晦涩的情况,这段代码没有正确处理,但解释它们很无聊和复杂,而且代码已经足够长的时间回答这个问题了.

There are a few obscure cases that this code doesn't handle correctly, but explaining them is boring and complicated, and the code has already made this answer long enough.

现在,这里有一些代码与 Twisted 基本相同.一、服务器:

Now, here's some code that does basically the same thing, with Twisted. First, the server:

from twisted.internet import reactor, protocol as p

class Echo(p.Protocol):
    def dataReceived(self, data):
        self.transport.write(data)

class EchoFactory(p.Factory):
    def buildProtocol(self, addr):
        print 'Connection by', addr
        return Echo()

reactor.listenTCP(5007, EchoFactory())
reactor.run()

现在,客户:

from twisted.internet import reactor, protocol as p

class EchoClient(p.Protocol):
    def connectionMade(self):
        self.transport.write(self.factory.data)

    def dataReceived(self, data):
        print 'Received:', data
        self.transport.loseConnection()

class EchoClientFactory(p.ClientFactory):
    protocol = EchoClient
    def __init__(self, data):
        self.data = data

reactor.connectTCP('localhost', 5007, EchoClientFactory('Hello, world'))
reactor.run()

我想提请您注意几件事.首先,Twisted 示例的长度缩短了 25%,即使对于如此微不足道的事情也是如此.asyncore 有 40 行,Twisted 只有 30 行.随着您的协议变得越来越复杂,这种差异会越来越大,因为您需要为 asyncore 编写越来越多的支持代码,而这些代码本来可以由 Twisted 提供.

There are a couple of things that I'd like to draw your attention to. First of all, the Twisted example is 25% shorter, even for something this trivial. 40 lines for asyncore, only 30 for Twisted. As your protocol grows more complex, this difference will get bigger and bigger, as you need to write more and more support code for asyncore that would have been provided for you by Twisted.

其次,Twisted 提供了一个完整的抽象.对于 asyncore 示例,您必须使用 socket 模块来进行实际的网络连接;asyncore 仅提供多路复用.如果您需要 在 Windows 等平台上的可移植行为,这是一个问题.这也意味着 asyncore 完全缺乏在其他平台上进行异步子进程通信的设施;你不能在 Windows 上将任意文件描述符塞进 select() 调用中.

Second, Twisted provides a complete abstraction. With the asyncore example, you have to use the socket module to do the actual networking; asyncore provides only multiplexing. This is a problem if you need portable behavior on platforms such as Windows. It also means that asyncore completely lacks facilities for doing asynchronous sub-process communication on other platforms; you can't stuff arbitrary file descriptors into a select() call on Windows.

第三,Twisted 示例是传输中性.EchoEchoFactoryEchoClientEchoClientFactory 都不是特定于 TCP 的.您可以将这些类变成一个可以通过 SSH、SSL、UNIX 套接字或管道连接的库,只需更改一个 connectTCP/listenTCP 调用在底部.这很重要,因为在您的协议逻辑中直接支持 TLS 之类的东西非常棘手.例如,TL​​S 中的写入"将触发较低级别的读取".因此,您需要将这些顾虑区分开来,以使它们正确.

Third, the Twisted example is transport neutral. None of Echo and EchoFactory and EchoClient and EchoClientFactory is in any way specific to TCP. You can make these classes into a library that can be connected via SSH, or SSL, or a UNIX socket, or a pipe, only by changing the one connectTCP/listenTCP call at the bottom. This is important, as supporting something like TLS directly in your protocol logic is very tricky. For example, a 'write' in TLS will trigger a 'read' at the lower level. So, you need to separate these concerns out to get them right.

最后,特定于您的用例,如果您直接处理 MAC 地址和以太网帧,Twisted 包含 双绞线,一个用于处理 IP 和以太网级网络的低级库.这不是 Twisted 维护最积极的部分;代码很旧.但是,它应该可以工作,如果不行,我们将认真对待其中的任何错误,并(最终)看到它们得到修复.据我所知,asyncore 没有可比的库,而且它本身当然不包含任何此类代码.

Finally, specific to your use-case, if you're dealing with MAC addresses and ethernet frames directly, Twisted contains Twisted Pair, a low-level library for dealing with IP and ethernet-level networking. This isn't the most actively maintained part of Twisted; the code is quite old. But, it should work, and if it doesn't we will take any bugs in it seriously and (eventually) see that they get fixed. As far as I'm aware, there's no comparable library for asyncore, and it certainly doesn't contain any such code itself.

这篇关于哪个 Python 异步库最适合我的代码?异步?扭曲?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆