2016-01-11 46 views
5

Sto provando a creare un elenco di porte disponibili in Python. Sto seguendo this tutorial, ma invece di stampare le porte aperte, le sto aggiungendo a un elenco.Perché le prese sono chiuse nel ciclo di comprensione degli elenchi ma non in ciclo?

Inizialmente, ho avuto qualcosa di simile al seguente:

available_ports = [] 

try: 
    for port in range(1,8081): 
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     result = sock.connect_ex((remoteServerIP, port)) 
     if result == 0: 
      available_ports.append(port) 
     sock.close() 

# ... 

Questo funziona chiaramente bene, ma è ben noto che comprehensions are faster than loops, così ora ho:

try: 
    available_ports = [port for port in range(1, 8081) if not socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex((remoteServerIP, port))] 

# ... 

ho assunto la prese wouldn essere chiuso, ma ho provato con il seguente:

try: 
    available_ports = [port for port in range(1, 8081) if not socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex((remoteServerIP, port))] 

    for port in range(1,8081): 
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     result = sock.connect_ex((remoteServerIP, port)) 
     if result == 0: 
      print("Port {}: \t Open".format(port)) 
     sock.close() 

# ... 

e in effetti th Sono state stampate le porte aperte.

Perché le prese sono chiuse nella comprensione ma non nel ciclo for? Posso fare affidamento su questo comportamento o questa è una falsa pista?

risposta

8

Non ci sono riferimenti ai socket aperti, il che significa che sono dati inutili. Le prese sono chiuse as soon as they are garbage collected.

Esattamente quando i socket dalla comprensione della lista sono garbage collection differenti tra le implementazioni Python. CPython utilizza il conteggio dei riferimenti e pertanto chiude i socket non appena viene eliminato l'ultimo riferimento. Altre implementazioni potrebbero rinviare la chiusura al prossimo ciclo del GC.

+0

Interessante. Mi sento anche se ci fosse un modo per GC manualmente i riferimenti, non sarebbe pietoso. Inoltre, non penso che ci sia un modo per chiudere i socket all'interno della comprensione (non 'con open (socket) as s'). Potrei aver bisogno di mangiare solo i pochi millisecondi necessari per aggiungere le porte. – erip

+1

Questa è una domanda diversa, ma se devi garantire la chiusura del socket, dovresti preferire il ciclo 'for'. –

+0

Nessuna domanda - solo riflessioni. Apprezzo l'aiuto e i riferimenti. – erip

Problemi correlati