¿Debo llamar a close () después de urllib.urlopen ()?

Soy nuevo en Python y leo el código de otra persona:

¿ urllib.urlopen() debe ser seguido por urllib.close() ? De lo contrario, uno perdería las conexiones, ¿correcto?

El método close debe urllib.urlopen en el resultado de urllib.urlopen , no en el módulo urllib sí mismo como está pensando (como menciona urllib.close , que no existe).

El mejor enfoque: en lugar de x = urllib.urlopen(u) , etc., use:

 import contextlib with contextlib.closing(urllib.urlopen(u)) as x: ...use x at will here... 

La statement with y el administrador de contexto de closing garantizarán el cierre correcto incluso en presencia de excepciones.

Como dice @Peter, las URL abiertas fuera del scope serán elegibles para la recolección de basura.

Sin embargo, también tenga en cuenta que urllib.py define:

  def __del__(self): self.close() 

Esto significa que cuando el recuento de referencia para esa instancia llegue a cero , se __del__ su método __del__ y, por lo tanto, también se llamará a su método de close . La forma más “normal” de que el recuento de referencias llegue a cero es simplemente dejar que la instancia salga del scope, pero no hay nada que lo detenga estrictamente de una __del__ explícita antes (sin embargo, no llama directamente a __del__ sino que reduce la referencia) contar por uno).

Sin duda, es un buen estilo para cerrar explícitamente sus recursos, especialmente cuando su aplicación corre el riesgo de usar demasiados recursos, pero Python lo limpiará automáticamente si no hace nada gracioso como mantener referencias (¿circulares?) a instancias que ya no necesitas más.

Estrictamente hablando, esto es cierto. Pero en la práctica, una vez (si) urllib sale del scope, la conexión será cerrada por el recolector de basura automático.

Básicamente , necesitas cerrar explícitamente la conexión cuando usas IronPython . El cierre automático al salir del scope se basa en la recolección de basura. Me encontré con una situación en la que la recolección de basura no se ejecutó durante tanto tiempo que Windows se quedó sin sockets. Estaba encuestando un servidor web a alta frecuencia (es decir, tan alto como IronPython y la conexión permitiría, ~ 7Hz). Pude ver que las “conexiones establecidas” (es decir, los sockets en uso) suben y suben en PerfMon. La solución fue llamar a gc.collect() después de cada llamada a urlopen .