2016-01-11 24 views
5

私は利用可能なポートの一覧をPythonで作成しようとしています。私はthis tutorialに従っていますが、開いているポートを印刷する代わりに、それらをリストに追加しています。なぜソケットはリストの理解で閉じられますが、forループでは閉じられませんか?

は当初、私は次のようなものを持っていた:

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

# ... 

これは明らかに正常に動作しますが、よくcomprehensions are faster than loopsので、私が今持っていることが知られている:

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

# ... 

私はソケットwouldnを仮定しました私は次のようにテストしました:

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

# ... 

本当にthオープンポートが印刷された。

なぜソケットは理解の中で閉じていますが、forループは閉じていませんか?私はこの行動に頼ることができますか、これは赤ちゃんですか?

答えて

8

オープンソケットに残っている参照はありません。つまり、ガベージコレクションされています。ソケットは閉じたas soon as they are garbage collectedです。

リストの理解のソケットがガベージコレクションされている場合は、Pythonの実装によって異なります。 CPythonは参照カウントを使用するため、最後の参照が削除されると直ちにソケットを閉じます。他の実装では、終了を次のGCサイクルに延期する可能性があります。

+0

興味深い。手動で参照をGCする方法があったとしても、私はpythonicではないと思う。私はまた、理解の範囲内でソケットを閉じる方法はないと考えています( 'open(socket)as s'はありません)。ポートを「追加」するのに数ミリ秒かかるだけで済むかもしれません。 – erip

+1

これは別の質問ですが、ソケットのクローズを保証する必要がある場合は、 'for'ループを使用するほうがいいと思います。 –

+0

質問はありません。私は助けと参考に感謝します。 – erip

関連する問題