(OSError) Ошибка обработчиков исключений (ConnectionRefusedError) - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь отловить ошибки в сокет-соединении с Python. Мне нужно работать с двумя разными типами ошибок [ConnectionRefusedError, OSError] . Я хочу выполнить различное действие для каждой ошибки, поэтому я сделал это с помощью оператора (за исключением, кроме), и когда код похож на показанный ниже [Которое (OSError) исключение пишется первым] , только Первое исключение [Который (OSError)] Повышается, даже если ошибка (ConnectionRefusedError)
Код:

for ip in ips:
    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    try :
        sock.connect((ip,12345))
        print("Up.")
        up.append(ip)
        sock.close()
    except OSError:
        print("Down.")
        raise
    except ConnectionRefusedError:
        print("Up.")
        up.append(ip)
    except Exception as e:
        print(e)
  • Выход: вниз.
  • Возникла ошибка: ConnectionRefusedError: [Errno 111] Соединение отклонено

Итак, исключение [OSError], которое содержит оператор raise, вызвало [ConnectionRefusedError] (которое является следующим оператором исключения!).

. Но когда я сначала поменяю местами исключения и запись (ConnectionRefusedError), все работает отлично:

for ip in ips:
    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    try :
        sock.connect((ip,port))
        print("Up.")
        sock.close()
    except ConnectionRefusedError:
        print("Up.")
        up.append(ip)
    except OSError:
        print("Down.")
        raise
    except Exception as e:
        print(e)

Итак, почему в первом случае исключение OSError обрабатывает ConnectionRefusedError? И есть ли способ написать исключение OSError в первую очередь, и он сразу работает?

1 Ответ

0 голосов
/ 07 января 2019

ConnectionRefusedError наследуется от OSError, поэтому предложение except, принимающее OSError, может просто соответствовать ConnectionRefusedError; в частности, учитывая, что предложения except проверяются в том порядке, в котором они написаны, если предложение OSError пишется первым, оно всегда будет соответствовать исключению ConnectionRefusedError.

Нет никакого способа обойти это 1 , поэтому, как правило, вы хотите всегда писать более конкретные обработчики исключений, а не более общие.


  1. Чтобы «исправить» это в общем случае, интерпретатору потребуется выполнить топологический вид предложений на основе отношений наследования для предложений исключения, возможно разделить предложения, которые определяют множественные исключения, и, учитывая динамический характер язык, делайте это во время выполнения, замедляя исключения для функции, которая редко имеет значение.
...