2016-01-11 41 views
5

Próbuję utworzyć listę dostępnych portów w Pythonie. Śledzę this tutorial, ale zamiast drukować otwarte porty, dodaję je do listy.Dlaczego gniazda są zamknięte na liście, ale nie w pętli for?

Początkowo miałem coś jak następuje:

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() 

# ... 

To wyraźnie działa dobrze, ale to jest dobrze znane, że comprehensions are faster than loops, więc teraz mam:

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

# ... 

Przypuszczałem gniazd wouldn Nie mogę być zamknięty, ale przetestowałem go pod następującym kątem:

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() 

# ... 

i rzeczywiście Otwarte porty zostały wydrukowane.

Dlaczego gniazda są zamknięte w zrozumieniu, ale nie w pętli for? Czy mogę polegać na tym zachowaniu, czy też jest to czerwony śledź?

Odpowiedz

8

Nie ma żadnych odniesień do otwartych gniazd, co oznacza, że ​​są to śmieci zebrane. Gniazda są zamknięte as soon as they are garbage collected.

Dokładnie, gdy gniazda ze zrozumienia listy są śmieci zbierane różni się między implementacjami Python. CPython używa liczenia odwołań i dlatego zamyka gniazda, gdy tylko odwołanie zostanie odrzucone. Inne implementacje mogą odroczyć zamknięcie do następnego cyklu GC.

+0

Interesujące. Czuję, że nawet gdyby istniał sposób ręcznego GC referencji, nie byłby to pyton. Nie sądzę też, że istnieje sposób na zamknięcie gniazd w ramach rozumienia (no 'with open (socket) as s'). Być może będę musiał po prostu zjeść kilka milisekund, które zajmuje "dołączenie" portów. – erip

+1

To naprawdę inne pytanie, ale jeśli musisz zagwarantować zamknięcie gniazda, myślę, że powinieneś po prostu wybrać pętlę 'for'. –

+0

Bez pytań - tylko zadumy. Doceniam pomoc i referencje. – erip

Powiązane problemy