Python 对扭曲回调使用异步/等待语法

Python 对扭曲回调使用异步/等待语法,python,asynchronous,twisted,python-3.5,python-asyncio,Python,Asynchronous,Twisted,Python 3.5,Python Asyncio,我想用Twisted方法使用async/await语法。但正如文档中所述,addCallbackcallback是同步调用的。我见过decorator用于此目的,但我更喜欢使用async/await语法(如果可能或有意义的话) 我从中获取了原始代码,但尝试将其迁移到async/await语法时运气不佳: import pika from pika import exceptions from pika.adapters import twisted_connection from twisted

我想用Twisted方法使用
async/await
语法。但正如文档中所述,
addCallback
callback是同步调用的。我见过decorator用于此目的,但我更喜欢使用
async/await
语法(如果可能或有意义的话)

我从中获取了原始代码,但尝试将其迁移到async/await语法时运气不佳:

import pika
from pika import exceptions
from pika.adapters import twisted_connection
from twisted.internet import defer, reactor, protocol, task


async def run_async(connection):
    channel = await connection.channel()
    exchange = await channel.exchange_declare(exchange='topic_link',type='topic')
    queue = await channel.queue_declare(queue='hello', auto_delete=False, exclusive=False)
    await channel.queue_bind(exchange='topic_link', queue='hello', routing_key='hello.world')
    await channel.basic_qos(prefetch_count=1)
    queue_object, consumer_tag = await channel.basic_consume(queue='hello', no_ack=False)
    l = task.LoopingCall(read_async, queue_object)
    l.start(0.01)


async def read_async(queue_object):
    ch,method,properties,body = await queue_object.get()
    if body:
        print(body)
    await ch.basic_ack(delivery_tag=method.delivery_tag)


parameters = pika.ConnectionParameters()
cc = protocol.ClientCreator(reactor, twisted_connection.TwistedProtocolConnection, parameters)
d = cc.connectTCP('rabbitmq', 5672)
d.addCallback(lambda protocol: protocol.ready)
d.addCallback(run_async)
reactor.run()
这显然不起作用,因为没有人等待
运行异步
函数。

正如臭名昭著的.no和Twisted文档所指出的那样,这是一条可行之路。不过,您必须包装回调结果,而不是回调本身,我不清楚

这就是它最终的样子:

def ensure_deferred(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        result = f(*args, **kwargs)
        return defer.ensureDeferred(result)
    return wrapper


@ensure_deferred
async def run(connection):
    channel = await connection.channel()
    exchange = await channel.exchange_declare(exchange='topic_link', type='topic')
    queue = await channel.queue_declare(queue='hello', auto_delete=False, exclusive=False)
    await channel.queue_bind(exchange='topic_link', queue='hello', routing_key='hello.world')
    await channel.basic_qos(prefetch_count=1)
    queue_object, consumer_tag = await channel.basic_consume(queue='hello', no_ack=False)
    l = task.LoopingCall(read, queue_object)
    l.start(0.01)


@ensure_deferred
async def read(queue_object):
    ch, method, properties, body = await queue_object.get()
    if body:
        print(body)
    await ch.basic_ack(delivery_tag=method.delivery_tag)


parameters = pika.ConnectionParameters()
cc = protocol.ClientCreator(reactor, twisted_connection.TwistedProtocolConnection, parameters)
d = cc.connectTCP('rabbitmq', 5672)
d.addCallback(lambda protocol: protocol.ready)
d.addCallback(run)
reactor.run()
谢谢。

正如臭名昭著的.no和Twisted文档所指出的,这是一条正确的道路。不过,您必须包装回调结果,而不是回调本身,我不清楚

这就是它最终的样子:

def ensure_deferred(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        result = f(*args, **kwargs)
        return defer.ensureDeferred(result)
    return wrapper


@ensure_deferred
async def run(connection):
    channel = await connection.channel()
    exchange = await channel.exchange_declare(exchange='topic_link', type='topic')
    queue = await channel.queue_declare(queue='hello', auto_delete=False, exclusive=False)
    await channel.queue_bind(exchange='topic_link', queue='hello', routing_key='hello.world')
    await channel.basic_qos(prefetch_count=1)
    queue_object, consumer_tag = await channel.basic_consume(queue='hello', no_ack=False)
    l = task.LoopingCall(read, queue_object)
    l.start(0.01)


@ensure_deferred
async def read(queue_object):
    ch, method, properties, body = await queue_object.get()
    if body:
        print(body)
    await ch.basic_ack(delivery_tag=method.delivery_tag)


parameters = pika.ConnectionParameters()
cc = protocol.ClientCreator(reactor, twisted_connection.TwistedProtocolConnection, parameters)
d = cc.connectTCP('rabbitmq', 5672)
d.addCallback(lambda protocol: protocol.ready)
d.addCallback(run)
reactor.run()

谢谢。

这是您想要的use@notorious.no我已经尝试将
cc.connectTCP('rabbitmq',5672)
包装为
defer.ensureDeferred
,但没有帮助。这就是你的意思吗?谢谢。不,我知道了。我必须用EnsureDerred来包装回调本身。我正在包装回调的结果,但显然没有成功。谢谢这就是你想要的use@notorious.no我已经尝试将
cc.connectTCP('rabbitmq',5672)
包装为
defer.ensureDeferred
,但没有帮助。这就是你的意思吗?谢谢。不,我知道了。我必须用EnsureDerred来包装回调本身。我正在包装回调的结果,但显然没有成功。谢谢