В Python, как правильно выйти из цикла While из Try?

Я пишу функцию Python для отправки запроса GET на URL-адрес с использованием предоставленных пользователем учетных данных и получения возвращенного токена для последующего использования.

# Function for logging in and get a valid token
def getToken():
    while True: # Loop the cycle of logging in until valid token is received
        try:
            varUsername = raw_input("Enter your username: ")
            varPassword = getpass.getpass("Enter your password: ")
            reqAuthLogin = 'https://MY_URL?username=' + varUsername + '&password=' + varPassword # Send the login request
            varToken =  json.loads(urllib2.urlopen(reqAuthLogin).read())['Token'] # Attempt to parse the JSON response and read the Token, if possible
        except: # If credential is invalid and no token returned
            os.system('cls')
            print 'Invalid credentials. Please try again. \n'
        else: # I want this Try to exit the while loop if login is successful
            break

    os.system('cls')
    return varToken # Return the retrieved token at the end of this function

Если комбинация имени пользователя и пароля неверна, код генерирует исключение KeyError. Я узнал, что Try-Else может сломать самый внутренний цикл, в данном случае это должен быть цикл while. В моем дизайне я хотел, чтобы функция выводила следующее сообщение при возникновении исключения (имеется в виду недействительные учетные данные):

Invalid credentials. Please try again.

Enter your username:

Если вход в систему выполнен успешно, код должен очистить экран и вернуть полученный токен. Проблема в том, что этот код работал хорошо, когда он не был ни в Try, ни в While. Теперь он выводит это при успешном входе в систему:

Enter your username:

По-видимому, программа не выполняет ветку Else, хотя исключений не возникает. Я новичок в Python, пожалуйста, помогите мне определить причину этой ошибки.

РЕДАКТИРОВАТЬ: Спасибо за совет в комментариях. Я установил несколько точек останова, но точки останова показали, что даже если я вставлю паузу в конце блока try, программа сначала выполнит ее, а затем сразу вернется к оператору «пока правда». Казалось, что break не удалось успешно выйти из цикла.


person xyx0826    schedule 20.12.2016    source источник
comment
Вы не должны использовать исключения для покемонов (должны поймать их всех).   -  person Moberg    schedule 20.12.2016
comment
Проще всего просто поставить break в конце try: block.   -  person RemcoGerlich    schedule 20.12.2016
comment
Поместите разрыв в фрагмент кода try.   -  person Luca Angioloni    schedule 20.12.2016
comment
Я бы установил точку останова в вашей попытке, чтобы убедиться, что у вас действительно есть работающий код, потому что с перехватом всех исключений трудно точно сказать, что не удается и по какой причине. Вам придется исследовать каждую строку, чтобы увидеть, что она делает.   -  person idjaw    schedule 20.12.2016
comment
Вы пытались запустить код без блока try...else для рабочих учетных данных? Вы получаете какие-либо ошибки?   -  person nael    schedule 20.12.2016
comment
@nmusleh Да, основной код работал довольно хорошо. Я уверен, что написал что-то не так в цикле while или try.   -  person xyx0826    schedule 20.12.2016
comment
@idjaw Спасибо за совет. Точки останова показали, что даже если я вставлю разрыв в конце блока try, программа сначала выполнит его, а затем сразу вернется к оператору while True. Казалось, что break не удалось успешно выйти из цикла.   -  person xyx0826    schedule 20.12.2016


Ответы (1)


Почему бы просто не добавить логическое значение, которое изменяется в конце успешной попытки?

# Function for logging in and get a valid token
def getToken():
    gotToken = False
    while not gotToken: # Loop the cycle of logging in until valid token is received
        try:
            varUsername = raw_input("Enter your username: ")
            varPassword = getpass.getpass("Enter your password: ")
            reqAuthLogin = 'https://MY_URL?username=' + varUsername + '&password=' + varPassword # Send the login request
            varToken =  json.loads(urllib2.urlopen(reqAuthLogin).read())['Token'] # Attempt to parse the JSON response and read the Token, if possible
            gotToken = True
        except: # If credential is invalid and no token returned
            os.system('cls')
            print 'Invalid credentials. Please try again. \n'
    os.system('cls')
    return varToken # Return the retrieved token at the end of this function
person lucianopaz    schedule 20.12.2016
comment
Благодарю вас! Ваше решение сработало. Хотя я не знаю, почему мой ELSE не работает, я буду использовать ваш метод в качестве замены... - person xyx0826; 20.12.2016