python - 哪个 Python 异步库最适合我的代码?异步?扭曲?

标签 python asynchronous twisted asyncore

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

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

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 方法看起来有点像这样:

def sniff_wifi(self):

    while True:
        yield mac_address

while True 循环显然会使它们阻塞。

我想为此使用 asyncore,因为它是标准库的一部分。没有第 3 方依赖项是奖励。但是,这并不意味着如果您建议我使用它,我就不会使用它...

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

最佳答案

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

很难在简短的回答中展示 Twisted 的所有优势(我如何在一个简短的示例中展示 http/dns/ssh/smtp/pop/imap/irc/xmpp/process-spawning/multi-threading 服务器?)将重点关注人们似乎对 Twisted 最常见的误解之一:它比 asyncore 更复杂或更难使用。

让我们从一个异步的例子开始。为了避免有偏见的介绍,我将使用仍然有点喜欢 asyncore 的其他人的示例。这是一个简单的异步示例 taken from Richard Jones' weblog(为简洁起见省略了注释)。

首先,这是服务器:

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()

有一些晦涩的情况,这段代码没有正确处理,但解释它们既无聊又复杂,而且代码已经让这个答案足够长了。

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

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 行。随着您的协议(protocol)变得越来越复杂,这种差异会越来越大,因为您需要为 Twisted 为您提供的 asyncore 编写越来越多的支持代码。

其次,Twisted 提供了一个完整的抽象。对于 asyncore 示例,您必须使用 socket 模块来进行实际的联网; asyncore 仅提供多路复用。如果您需要 portable behavior on platforms such as Windows ,这是一个问题。这也意味着 asyncore 完全缺乏在其他平台上进行异步子进程通信的设施;您不能将任意文件描述符填充到 Windows 上的 select() 调用中。

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

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

关于python - 哪个 Python 异步库最适合我的代码?异步?扭曲?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4384360/

相关文章:

twisted - 使用 deferred 进行无限调用循环

python - python 中的 anagram 列表列表

python - 将 django 的 auth_user 与现有用户表合并

node.js - Node.js 中回调函数的返回值

c# - 使用 C# 进行异步或批处理

c# - 从异步方法更新 GUI

python - autobahn.twisted.wamp.Application 可以发布/订阅吗?

python - Twisted:将 ReconnectingClientFactory 与 SSL 混合并使 write() 为 "reliable"

python:将字符串的二维列表转换为 float

javascript - Bootstrap表导出数据问题