Закрытие сокетов в питоне - PullRequest
4 голосов
/ 05 октября 2009

Я изменяю код Python, который имеет эту форму:

def foo(self):
    try:
        connect socket
    except Exception, e:
        some error reporting stuff
        return an error

    use the socket
    do some other stuff

    if some condition:
        return

    do some more stuff
    socket.close()
    return normally

Исходя из Java, я хотел бы попробовать - наконец-то, чтобы убедиться, что сокет закрыт. Должен ли этот код также иметь это, или это какая-то Питонская магия, происходящая на заднем плане, которая делает его таким, чтобы вам не пришлось?

Я прочитал в документации по питону, что сокеты закрываются, когда они собирают мусор. Но полагаться на сборщик мусора, чтобы закрыть свои розетки, не очень хорошо.

Ответы [ 3 ]

12 голосов
/ 05 октября 2009

Вы можете использовать блок try-finally, который был добавлен в Python 2.5:

try:
    open socket
    do stuff with socket
finally:
    close socket

Или вы можете использовать оператор with, который был добавлен в Python 2.6 (и может использоваться в 2.5 с объявлением from __future__ import with_statement):

with open_the_socket() as s:
    use s

Это автоматически закроет сокет при выходе из внутреннего блока, независимо от того, был ли он завершен нормально или через исключение, при условии, что класс сокета закрывается в своем методе __exit__().

Начиная с Python 2.7.2, метод __exit__() не реализован в классе сокетов.

1 голос
/ 05 октября 2009

Вы, кажется, хотите добавить блок finally, чтобы попытаться / за исключением 2.5

http://docs.python.org/whatsnew/2.5.html#pep-341-unified-try-except-finally

Вы правы, полагаясь на то, что автоматическое закрытие при сборе мусора является плохой практикой. Лучше закрыть их, когда вы закончите с ними. Попытка / наконец - хороший способ сделать это.

Не забудьте вызвать shutdown () перед закрытием ().

0 голосов
/ 05 октября 2009

В дополнение к блоку try / finally, рассмотрите возможность установки таймаута сокета по умолчанию, который автоматически закроет сокет (ы) по истечении заданного вами времени.

http://docs.python.org/library/socket.html?highlight=setdefaulttimeout#socket.setdefaulttimeout

...