Asyncio create_connection protocol factory

The create_connection function from the Python 3 asynchronous module takes the factory protocol as the first parameter. The documentation states the following:

Note protocol_factory can be any callable, not necessarily a class. For example, if you want to use a pre-created protocol instance, you can pass lambda: my_protocol.

So you can pass the instance with lambda, for example:

create_connection(lambda: Protocol(a, b, c))

An alternative would be to __call__to return self, so that you can just pass the instance without a lambda definition.

protocol = Protocol(a, b, c)
create_connection(protocol)

Is there a reason to use lambda, as the documentation suggests by definition __call__in a class?

+4
source share
2 answers

Notice the difference between these two lines:

loop.create_connection(MyProtocol, '127.0.0.1', 8888)    # Option #1
loop.create_connection(MyProtocol(), '127.0.0.1', 8888)  # Option #2

Here is an example echo client from asyncio docs, modified to work with Option # 1:

class MyEchoClientProtocol(asyncio.Protocol):
    def connection_made(self, transport):
        message = "hello"
        transport.write(message.encode())
        print('Data sent: {!r}'.format(message))

    def data_received(self, data):
        print('Data received: {!r}'.format(data.decode()))

    def connection_lost(self, exc):
        print('The server closed the connection')
        print('Stop the event loop')
        loop.stop()


loop = asyncio.get_event_loop()
coro = loop.create_connection(MyEchoClientProtocol, '127.0.0.1', 8765)
loop.run_until_complete(coro)
loop.run_forever()
loop.close()

If you decide to use Option # 2, you will need to implement MyProtocol.__call__(self)one that works with instances MyProtocol .

Although this may work fine for create_connection, since yours __call__will only be called once, this does not work well for the parameter :protocol_factory create_server

...
# Each client connection will create a new protocol instance
coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8888)
...

It protocol_factoryis called several times to create new instances Protocol. Usage EchoServerClientProtocol()and definition def __call__(self): return selfwill use only one instance Protocol!

0

:

, - .

:

BaseEventLoop.create_connection BaseEventLoop._create_connection_transport ref, Protocol :

    protocol = protocol_factory()

, , :

class Prococol:
   pass

def create_connection(Protocol):
   protocol = Protocol()

create_connection(Protocol)

, "protocol = Protocol()" . :

class Protocol:
  def __init__(self, a):
     self.a = a

def create_connection(Protocol):
  protocol = Protocol()

create_connection(lambda: Protocol(1))

, OP :

class Protocol:
  def __init__(self, a):
     self.a = a

  def __call__(self):
     return self

def create_connection(Protocol):
  protocol = Protocol()

create_connection(Protocol(1))

, , , , . , - , create_connection(lambda: Protocol(1)) , create_connection, , , , , .

Udi , def __call__(self): return self create_server (, , ), -. , , , , create_server. :

class Protocol:
  def __init__(self, a):
     self.a = a

  def __call__(self):
     return Protocol(self.a)

__call__, -. , , .

0

Source: https://habr.com/ru/post/1667175/


All Articles