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

eri*_*rip 5 python sockets list-comprehension

我正在尝试在Python中创建可用端口列表.我正在学习本教程,但不是打印开放端口,而是将它们添加到列表中.

最初,我有类似以下内容:

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

# ...
Run Code Online (Sandbox Code Playgroud)

这显然工作正常,但众所周知,理解比循环更快,所以我现在有:

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

# ...
Run Code Online (Sandbox Code Playgroud)

我假设套接字不会关闭,但我测试了以下内容:

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

# ...
Run Code Online (Sandbox Code Playgroud)

确实打开了开放的港口.

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

Emi*_*röm 8

打开的套接字没有任何引用,这意味着它们是垃圾回收的.一旦垃圾收集,套接字就会关闭.

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