Как читать входные данные Python в виде целых чисел
Оглавление
- Как получить целочисленные входные значения в Python
- Работа с Недопустимыми входными Данными
- Фильтрация вводимых данных на наличие допустимых целых чисел
- Создание служебной функции для чтения допустимых целых чисел
- Заключение
- Следующие шаги
Если вы когда-либо создавали интерактивное текстовое приложение на Python, то вы, вероятно, обнаружили, что вам нужен надежный способ запрашивать у пользователя целые числа в качестве входных данных. Недостаточно просто отобразить запрос и затем выполнить сбор данных о нажатиях клавиш. Вы должны убедиться, что вводимые пользователем данные действительно представляют собой целое число. Если это не так, то ваш код должен отреагировать соответствующим образом — как правило, повторив запрос.
В этом руководстве вы узнаете, как создать повторно используемую служебную функцию, которая гарантирует допустимые целочисленные входные данные от интерактивного пользователя. Попутно вы узнаете об инструментах Python для получения строки из консоли и преобразования этой строки в целое число.
Всякий раз, когда вы пишете программу, которая взаимодействует с клавиатурой, вы должны использовать защитный код для управления недопустимыми вводимыми данными, так что вы также узнаете наиболее простой способ справиться с этой ситуацией на языке Python. Вы будете надежно обрабатывать любые ошибки внутри функции, которая гарантированно не вернет ничего, кроме целых чисел.
Как получить целочисленные входные значения в Python
Стандартная библиотека Python предоставляет встроенный инструмент для получения строковых данных, вводимых пользователем, - функцию input(). Прежде чем начать использовать эту функцию, дважды проверьте, используете ли вы версию Python 3. Если вы хотите узнать, почему это так важно, ознакомьтесь с разделом, посвященным сворачиванию, ниже:
Версия функции input() в Python 2 была небезопасной, поскольку интерпретатор на самом деле выполнял строку, возвращаемую функцией, до того, как у вызывающей программы была какая-либо возможность ее проверить. Это позволило злоумышленнику внедрить в программу произвольный код.
Из-за этой проблемы в Python 2 также была предусмотрена функция raw_input() как гораздо более безопасная альтернатива, но всегда существовал риск, что ничего не подозревающий программист может выбрать более очевидное название input().
Python 3 переименовал raw_input() в input() и удалил старую, опасную версию input(). В этом руководстве вы будете использовать Python 3, так что этот подводный камень не вызовет беспокойства.
В Python 3 функция input() возвращает значение string,, поэтому вам нужно преобразовать его в целое число. Вы можете прочитать строку, преобразовать ее в целое число и вывести результаты в виде трех строк кода:
>>> number_as_string = input("Please enter an integer: ")
Please enter an integer: 123
>>> number_as_integer = int(number_as_string)
>>> print(f"The value of the integer is {number_as_integer}")
The value of the integer is 123
Когда выполняется приведенный выше фрагмент кода, интерпретатор останавливается на функции input() и предлагает пользователю ввести целое число. В конце запроса отображается мигающий курсор, и система ожидает, пока пользователь введет произвольную строку символов.
Когда пользователь нажимает клавишу , функция возвращает строку, содержащую введенные символы, без перевода строки. В качестве напоминания о том, что полученное значение является строкой, вы присвоили имя принимающей переменной number_as_string.
Ваша следующая строка пытается преобразовать number_as_string в целое число и сохранить результат в number_as_integer. Для выполнения преобразования используется конструктор int() class. Наконец, функция print() выводит результат.
Работа с недопустимыми входными данными
Вы, наверное, уже заметили, что приведенный выше код безнадежно оптимистичен. Вы не всегда можете положиться на то, что пользователи предоставят те данные, которые вы ожидаете. Вы можете оказать большую помощь, предоставив четкое сообщение-подсказку, но из-за путаницы, небрежности или злого умысла всегда найдутся пользователи, которые введут неверные данные. Ваша программа должна быть готова к работе с любым типом текста.
Функция input() может возвращать произвольный текст или даже пустую строку, если пользователь нажал И сразу же ввел в командной строке. Как вы можете гарантировать, что ваша программа не попытается выполнить арифметические действия с путаницей символов, когда она ожидает int?
Вы собираетесь использовать собственный механизм обработки ошибок в Python. По умолчанию при преобразовании целых чисел возникает ValueError исключение в случае сбоя. Повторите приведенный выше код, но на этот раз обратите внимание, как он ведет себя при неправильном вводе:
>>> number_as_string = input("Please enter an integer: ")
Please enter an integer: rutabaga
>>> number_as_integer = int(number_as_string)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'rutabaga'
Вы заметите, что эта ошибка возникает не в той строке, где вводится значение, а в той, где вы пытаетесь преобразовать его с помощью встроенной функции int(). Вы сами должны обработать это исключение ValueError, если оно возникнет.
Кажется, требуется немного больше внимания, чтобы ваша программа получала правильные целочисленные значения. Об этом вы позаботитесь в следующий раз.
Фильтрация вводимых данных на наличие допустимых целых чисел
Вы видели, что функция стандартной библиотеки Python input() позволяет пользователю вводить в командной строке практически все, что угодно. Вы должны быть уверены, что можете интерпретировать полученную информацию как целое число.
Здесь вы можете воспользоваться одним из двух подходов: LBYL или EAFP, что означает Смотри, прежде чем прыгнуть и Легче попросить прощения, чем разрешения соответственно. В принципе, в LBYL вы стремитесь предотвращать возникновение ошибок. EAFP фокусируется на обработке ошибок после их возникновения.
Вкратце, стратегия LBYL заключалась бы в тщательной проверке входных данных перед попыткой преобразования. EAFP, с другой стороны, с головой погружается в работу, немедленно пытаясь выполнить преобразование, рассчитывая на то, что обработка исключений Python справится с любыми ошибками.
Хотя LBYL может показаться более сложным подходом, он часто вводит сложную логику проверки на ошибки и условные потоки в то, что должно быть простой операцией. Кроме того, вы должны выполнять проверку на ошибки при каждом вводе, даже если он корректен.
В вашем случае проверки целых чисел подход EAFP приводит к тому, что код становится не только проще, но и быстрее. Если указано допустимое целое число, вы не будете тратить время на проверку несуществующих ошибок. С другой стороны, если строка неверна, то Python выдаст встроенное исключение ValueError.
В Python исключения обрабатываются в виде try ... except блока. Заключая блок try ... except в цикл while, вы можете гарантировать, что через него пройдут только целые числа. Подобный механизм иногда называют циклом повторных попыток .
Вот пример того, как вы можете написать этот практически пуленепробиваемый код:
1>>> number_as_integer = None
2>>> while number_as_integer is None:
3... try:
4... number_as_integer = int(input("Please enter an integer: "))
5... except ValueError:
6... print("Invalid integer!")
7...
8>>> print(f"The integer you entered was {number_as_integer}")
Вы вложили вызов input() в вызов int(). Это не повредит, поскольку сбой может произойти только в int() функции.
Теперь, если пользовательская строка может быть проанализирована как допустимое целое число, то этому значению присваивается значение number_as_integer, прежде чем интерпретатор вернется к началу цикла и повторно проверит условие while. Поскольку теперь это условие равно False, цикл завершается, и выполнение продолжается в строке 8 с допустимым целым значением.
Если, однако, введенная пользователем строка неверна, то генерируется ValueError и интерпретатор переходит прямо к ветви except, где выводит сообщение об ошибке, прежде чем вернуться к while заявление в строке 2. В этом случае number_as_integer по-прежнему равно None, поэтому цикл выполняется снова.
Результатом этой логики является то, что ваш код просто отказывается продолжать работу, пока не получит допустимое целое число.
Создание служебной функции для чтения допустимых целых чисел
Приведенный выше код работает достаточно хорошо, но его не очень удобно использовать повторно. Если вы скопируете и вставите его в какую-либо другую логику, то вам, вероятно, потребуется изменить имя переменной number_as_integer и изменить подсказки в соответствии с новой ситуацией. Такой подход может привести к неосторожным ошибкам.
Было бы гораздо лучше обернуть код в вашу собственную надежную функцию. После надлежащего тестирования вы можете рассматривать эту функцию как своего рода черный ящик — надежный источник целых чисел, вводимых пользователем без особых усилий, для всех ваших проектов.
Вот как это можно сделать. Поскольку вы можете повторно использовать свою функцию в различных ситуациях, она выдаст настраиваемое приглашение, а также необязательное сообщение об ошибке:
>>> def get_integer(prompt: str, error_message: str = "") -> int:
... while True:
... try:
... return int(input(prompt))
... except ValueError:
... print(error_message)
...
Преимущество наличия в вашем арсенале функции, подобной get_integer(), заключается в том, что она внутренне устраняет распространенные ошибки, поэтому вызывающий ее код может оставаться простым. После того, как вы определили свою новую функцию в REPL, как указано выше, вот как вы можете протестировать ее:
>>> print(get_integer("Please enter an integer: "))
Please enter an integer: foobar
Please enter an integer:
Please enter an integer: -123
-123
>>> print(
... get_integer(
... prompt="Enter a value for n: ",
... error_message="n must be an integer."
... )
... )
Enter a value for n: jabberwocky
n must be an integer.
Enter a value for n: 3.1415
n must be an integer.
Enter a value for n: 999
999
Если вы считаете функцию get_integer() полезной, то вы можете сохранить ее в модуле для импорта. Освоение абсолютного и относительного импорта в Python - это отличный навык, который может повысить возможность повторного использования вашего кода.
В демонстрационных целях вы можете просто сохранить функцию в точности так, как вы определили ее выше, в файле с именем get_integer.py. Затем, чтобы сделать его доступным для другого модуля в той же виртуальной среде и в том же каталоге, вам просто нужна следующая строка вверху test.py, например:
# test.py
from get_integer import get_integer
Функция get_integer() является очень простым примером повторно используемого кода. После сохранения ее в модуле вы можете вызывать ее всякий раз, когда вам понадобится надежный способ получения целых чисел от пользователя.
Заключение
Теперь вы готовы без опаски воспринимать вводимые пользователем данные! Даже если ваш пользователь сначала не введет правильное целое число, вы можете быть уверены, что никакие ненужные данные никогда не попадут в вашу программу. Ваша функция будет упорно продолжать запрашивать входные данные, пока не получит допустимое целое число. Покончив с этой проблемой, вы можете сосредоточиться на более интересных частях вашего проекта.
В этом руководстве вы узнали, как:
- Используйте функцию
input()стандартной библиотеки Python, чтобы получить ввод строки от пользователя - Преобразовать строковое значение в целочисленное
- Обрабатывать ошибки, когда входная строка не является правильно сформированным целым числом
- Создайте надежную функцию многократного использования, которую вы можете использовать во многих проектах
Повторное использование кода - важная тема в разработке программного обеспечения. Лучший способ создать надежный код - это использовать небольшие надежные компоненты. Ваша функция get_integer() является одним из примеров этого.
Скачать бесплатно: Нажмите здесь, чтобы загрузить пример кода, который вы будете использовать для получения целочисленных данных от пользователей в Python.
Следующие шаги
В этом руководстве вы рассмотрели одну конкретную стратегию проверки правильности пользовательского ввода. Теперь, когда вы понимаете, что входит в базовую проверку вводимых данных в Python, вас могут заинтересовать некоторые проекты с открытым исходным кодом, которые не только решают эту проблему, но и включают в себя некоторые более сложные функциональные возможности:
Вот пример того, как вы могли бы использовать cooked_input.get_int() точно так же, как вашу пользовательскую функцию get_integer():
from cooked_input import get_int
age = get_int(prompt="Enter your age")
Если вам нужны более подробные сведения об операциях ввода и вывода в Python в целом, то вы можете прочитать Основные принципы ввода, вывода и форматирования строк в Python и официальный документация. Кроме того, вы можете найти дополнительную информацию о числовых типах Python в руководстве Числа в Python.
Пусть все ваши целые числа будут действительными!