example - ¿Cómo usar socket en Python como administrador de contexto?
socket python 3 español (3)
Eche un vistazo a los siguientes fragmentos, tanto para sockets TCP como UDP
import socket
from contextlib import contextmanager
@contextmanager
def tcp_connection_to(*args, **kwargs):
s = socket.create_connection(*args, **kwargs)
yield s
s.close()
@contextmanager
def udp_connection():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
yield s
s.close()
Para que pueda usarlos de la siguiente manera:
MY_SERVER = (''localhost'', 5000) # Yes, we need tuple here
some_data = bytes("Hello.")
with tcp_connection_to(MY_SERVER) as conn:
conn.send(some_data)
with udp_connection() as conn:
conn.sendto(some_data, MY_SERVER)
También intenté enfatizar la diferencia en el comportamiento y el enfoque del término "conexión" entre TCP y UDP en los nombres de los métodos.
Parece que sería natural hacer algo como:
with socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
pero Python no implementa un administrador de contexto para socket. ¿Puedo usarlo fácilmente como administrador de contexto? De ser así, ¿cómo?
El módulo de socket
es bastante bajo, lo que le brinda acceso casi directo a la funcionalidad de la biblioteca C.
Siempre puede usar el decorador contextlib.contextmanager
para crear el suyo propio:
import socket
from contextlib import contextmanager
@contextmanager
def socketcontext(*args, **kw):
s = socket.socket(*args, **kw)
try:
yield s
finally:
s.close()
with socketcontext(socket.AF_INET, socket.SOCK_DGRAM) as s:
o use contextlib.closing()
para lograr el mismo efecto:
from contextlib import closing
with closing(socket.socket(socket.AF_INET, socket.SOCK_DGRAM)) as s:
pero el decorador de contextmanager()
te da la oportunidad de hacer otras cosas con el socket primero.
Python 3.x convierte a socket()
un administrador de contexto, aunque la documentación no menciona eso. Consulte la clase de socket
en el código fuente, que agrega los métodos __enter__
y __exit__
.
El módulo de socket es solo una envoltura alrededor de la interfaz de socket BSD. Es de bajo nivel, y realmente no intenta ofrecerle una API Pythonic práctica o fácil de usar. Es posible que desee utilizar algo de mayor nivel.
Dicho esto, de hecho implementa un administrador de contexto:
>>> with socket.socket() as s:
... print(s)
...
<socket.socket object, fd=3, family=2, type=1, proto=0>
Pero necesitas usar Python 3.
Para compatibilidad con Python 2 puede usar contextlib
.
from contextlib import closing
import socket
with closing(socket.socket()) as s:
print s