Найти - Пользователи
Полная версия: Перехват ValueError в функции модуля
Начало » Python для новичков » Перехват ValueError в функции модуля
1
Wannabee
Всем привет.
Занимаюсь по книге Майкла Доусона, нужно создать игру Блэкджек. Игра состоит из трех отдельных файлов:
  1. 1. Модуль cards.py, в котором определены базовые классы для карточных игр, Card, Hand, Deck
  2. 2. Модуль games.py с базовым классом для создания игрока, Player. И в нем же отдельно 2 функции - ask_yes_no() и ask_number().
  3. 3. blackjack.py с основным кодом для запуска игры, в котором также создаются классы-потомки для игры в блэкджек, основанные на тех, что в cards.py и games.py.

В общем, я пытаюсь прикрутить перехват ValueError в функции ask_number() из модуля games.py.
Вот такая функция была изначально:
def ask_number(question, low, high):
  response = None
  while response not in range(low, high):
      response = int(input(question))
      return response

В основном файле игры blackjack.py эта функция вызывается в таком контексте:
import games
import cards
...
def main(): 
    ...
    names = []
    number = games.ask_number("How many players? (1 - 7): ", low=1, high=8)
    for i in range(number):
        name = input("Enter player name: ")
        names.append(name)

Мне нужно чтобы в самой функции перехватывалось исключение ValueError при вводе неправильного значения, и чтобы это происходило до тех пор пока не ввести именно цифру, потому что потом response = int(input) будет пробовать преобразовать значение в число.
Я сделал вот так:
def ask_number(question, low, high):
    response = None
    while response not in range(low, high):
        try:
            response = int(input(question))
        except ValueError:
            print("Looks like it's not a number!")
        else:
            return response

Проблема в том, что когда я вызываю эту функцию непосредственно в модуле games.py и передаю ей неподходящее значение (вместо числа букву или пустую строку, например), ValueError нормально перехватывается и программа просит ввести число, пока его не получит. Но когда функция вызывается в самом файле игры посредством games.ask_number(…), то все равно возникает ошибка ValueError, как если бы в функции не было try/except:
Traceback (most recent call last): 
  File "D:/My Projects/BlackJack.py", line 164, in <module>
    main()
  File "D:/My Projects/BlackJack.py", line 150, in main
    number = games.ask_number("How many players? (1 - 7): ", low=1, high=8)
  File "D:/My Projects/games.py", line 21, in ask_number
    response = int(input(question))
ValueError: invalid literal for int() with base 10: 's'

Почему так происходит, и где закралась ошибка? Уж совсем вариантов нет
FishHook
1. response not in range(low, high)
Это что такое? Для того чтобы определить, попадает ли число в интервал от 0 до миллиона, вы будете перебирать миллион значений? Конгениально!!!!
2.
Wannabee
вызываю эту функцию непосредственно в модуле games.py и передаю ей неподходящее значение
Вот сигнатура функции
def ask_number(question, low, high)
какое такое такое неподходящее значение вы передаете? Ошибка возникает не на переданном значении, а на введенном с клавиатуры
FishHook
Wannabee
Уж совсем вариантов нет
Весь код покажите, можно архивом
Wannabee
1. response not in range(low, high)
Это что такое? Для того чтобы определить, попадает ли число в интервал от 0 до миллиона, вы будете перебирать миллион значений? Конгениально!!!!
1. Я даже не знаю. А зачем мне перебирать миллион значений, не подскажите? Или бывали прецеденты партии в 21 очко на миллион игроков? Тут планируется максимум 7 игроков, и в основном коде границы перебора по-моему довольно четко определены и переданы функции. Будет максимум range(1,8):
number = games.ask_number("How many players? (1 - 7): ", low=1, high=8)
Код для игры составлял сам автор книги. Я лишь выполняю задание по этой главе. По заданию надо реализовать перехват ошибок в “уязвимых местах” игры.
Вот сигнатура функции
def ask_number(question, low, high)
какое такое такое неподходящее значение вы передаете? Ошибка возникает не на переданном значении, а на введенном с клавиатуры
2. Это я понял, я неправильно сформулировал мысль. Проблема как раз с вводом с клавиатуры. Вот например когда функция ask_number() из games.py вызывается в главном файле blackjack.py, и она просит ввести число, чтобы установить количество игроков, то можно, допустим, “случайно” ввести букву, которую int(input(question)) не сможет преобразовать в числовой тип, и возникнет ValueError. Я добавил в функцию ask_number(question, low, high) конструкцию перехвата ValueError. То бишь чтобы если ввести букву, ValueError перехватывался и функция из модуля games.py опять просила ввести с клавиатуры число от 1 до 7. И так до тех пор, пока его не получит.
Перехват срабатывает, если например вызвать ask_number() непосредственно в самом модуле games.py, где она и определена, и ввести вместо цифры букву - ValueError перехватывается и функция опять просит ввести число. Но почему-то если функция вызывается в главном файле blackjack.py, то перехвата не происходит и возникает ValueError.

Код с тремя файлами прикрепил.
FishHook
Wannabee
А зачем мне перебирать миллион значений, не подскажите?
Я то откуда знаю, ты ж перебираешь, а не я.
Вот скажи, друг, зачем тебе всё это надо? Какова конечная цель? Не игру же написать, вообще, в общем и целом зачем?
FishHook
Какая версия питона?
py.user.next
Wannabee
Код для игры составлял сам автор книги.
Wannabee
while response not in range(low, high):
Вот это Доусон писал?

while not low <= response <= high:
Это даже не то же самое, потому что range() возьмёт только до high - 1.

Wannabee
Вот такая функция была изначально:
def ask_number(question, low, high):
  response = None
  while response not in range(low, high):
      response = int(input(question))
      return response
Да? И в чём смысл этого while'а? (Допустим, что это учебный while какой-то.)

Wannabee
number = games.ask_number("How many players? (1 - 7): ", low=1, high=8)
Надо тебе сменить учебник, а то он научит такой вот бред делать.
Параметр high должен принимать 7 и расчитывать на 7, а не принимать 8 и расчитывать на 7.
Подогнал интерфейс метода под его внутреннее устройство.
Видимо, Доусон очень часто потом ловит баги странного происхождения в своих программах и считает это неотъемлемой частью программирования.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB