为什么套接字在列表理解中关闭但在for循环中没有?

时间:2016-01-11 15:58:35

标签: python sockets list-comprehension

我试图在Python中创建可用端口列表。我正在关注this tutorial,但我没有打印开放端口,而是将它们添加到列表中。

最初,我有以下内容:

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

# ...

我认为套接字不会被关闭,但我测试了以下内容:

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

# ...

确实打开了端口。

为什么在理解中关闭套接字而不是for循环?我能依靠这种行为还是红鲱鱼?

1 个答案:

答案 0 :(得分:8)

打开的套接字没有任何引用,这意味着它们是垃圾回收的。套接字已关闭as soon as they are garbage collected

确切地说,当列表解析中的套接字被垃圾收集时,Python实现之间会有所不同。 CPython使用引用计数,因此在删除最后一个引用后立即关闭套接字。其他实现可能会将结束推迟到下一个GC周期。