【问题标题】:What are the requirements of a protocol factory in python asyncio?python asyncio中协议工厂的要求是什么?
【发布时间】:2016-09-14 15:29:08
【问题描述】:

我在看UDP echo server的例子:

import asyncio

class EchoServerProtocol:
    def connection_made(self, transport):
        self.transport = transport

    def datagram_received(self, data, addr):
        message = data.decode()
        print('Received %r from %s' % (message, addr))
        print('Send %r to %s' % (message, addr))
        self.transport.sendto(data, addr)

loop = asyncio.get_event_loop()
print("Starting UDP server")
# One protocol instance will be created to serve all client requests
listen = loop.create_datagram_endpoint(
    EchoServerProtocol, local_addr=('127.0.0.1', 9999))
transport, protocol = loop.run_until_complete(listen)

try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

transport.close()
loop.close()

看来是来电了……

loop.create_datagram_endpoint(EchoServerProtocol, local_addr=('127.0.0.1', 9999))

...正在这里完成所有工作。 method documentation 为第一个参数 (protocol_factory) 声明以下内容:

protocol_factory 必须是返回协议实例的可调用对象。

我的问题:

  • 什么定义了protocol instance
  • returning a protocol instanceinitiating a protocol object 的不同写法吗?
  • 示例中的EchoServerProtocol 如何满足此要求?

【问题讨论】:

    标签: python python-3.5 python-asyncio


    【解决方案1】:

    什么定义了协议实例

    协议是您定义的一个类,它实现了Protocols section 中定义的接口之一,即为一组回调提供实现,例如Connection Callbacks.

    因此,对于您发布的 UDP 回显服务器示例,EchoServerProtocol 用户定义类实际上通过实现 connection_madedatagram_received 来定义协议。

    总而言之,如果您在一个类中实现其中一个回调,则可以说您定义了一个Protocol。因此,该类的实例/对象将是一个协议实例


    返回一个协议实例是不是启动一个协议对象的不同措辞?

    正式。在您返回一个协议实例之前,您需要初始化它。所以基本上一个是另一个的先决条件。


    示例中的EchoServerProtocol 如何满足这个要求?

    首先,正如第一个问题所回答的那样,EchoServerProtocol 定义了一个协议。因此接下来的事情是提供一个protocol_factory,即defined

    protocol_factory 必须是返回协议实例的可调用对象。

    所以要满足这个要求,你可以有这个简单的方法:

    def my_protocol_factory():
        return EchoServerProtocol()
    

    注意,这个工厂首先初始化协议实例,然后返回它。

    所以在这个例子中可能会让你感到困惑的是,EchoServerProtocol 类本身是作为protocol_factory 传递的,但是如果你总结一下我所说的,你会发现EchoServerProtocol 实际上是一个可调用对象,当它被调用时,即EchoServerProtocol(),它实际上初始化了一个EchoServerProtocol 实例,并返回它。

    是的,这个例子满足了要求。


    【讨论】:

    • 我知道我不应该这样做。但这是一个美丽的答案:) 谢谢
    • 对我来说也一样 :) 很高兴它有帮助!!
    • 另外,这里有一个来自数据模型部分的简明定义,它以这种方式定义类。 类是可调用的。这些对象通常充当其自身新实例的工厂。
    猜你喜欢
    • 2017-06-03
    • 2021-12-30
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-28
    • 2017-08-06
    • 2016-05-30
    相关资源
    最近更新 更多