Полезно ли использовать вход Python над raw_input?
В настоящее время я преподаю первый курс студентам в университете, и я был удивлен, узнав, что, казалось бы, безобидная функция input
, которую некоторые из моих учеников решили использовать (и были смущены странным поведением), скрывал вызов на eval
за ним.
Итак, мой вопрос: почему функция input
вызывает eval
, и что бы это было полезно для этого, было бы безопаснее делать с raw_input
? Я понимаю, что это было изменено в Python 3, но в первую очередь это кажется необычным дизайнерским решением.
Документация по функциям ввода-вывода Python 2.x
Ответы
Ответ 1
Полезно ли использовать вход Python 2 над raw_input?
Нет.
input()
оценивает код, который пользователь дает. Он ставит всю мощь Python в руки пользователя. С выражениями генераторов/списков, __import__
, а операторы if/else
, буквально все, что может сделать Python, могут быть достигнуты с помощью одного выражения. Вредоносные пользователи могут использовать input()
для удаления файлов (__import__('os').remove('precious_file')
), monkeypatch остальной части программы (setattr(__import__('__main__'), 'function', lambda:42)
),... что угодно.
Обычным пользователям не нужно будет использовать все расширенные функции. Если вам не нужны выражения, используйте ast.literal_eval(raw_input())
- функция literal_eval
безопасна.
Если вы пишете для продвинутых пользователей, дайте им лучший способ ввода кода. Плагины, пользовательские модули и т.д. - что-то с полным синтаксисом Python, а не только с функциональностью.
Если вы абсолютно уверены, что знаете, что делаете, скажите eval(raw_input())
. eval
кричит: "Я опасен!" к обученному глазу. Но, скорее всего, вам это никогда не понадобится.
input()
была одной из старых ошибок дизайна, которые Python 3 решает.
Ответ 2
Функция ввода Python возвращает объект, результат
оценки выражения.
Функция raw_input возвращает строку
name = "Arthur"
age = 45
first = raw_input("Please enter your age ")
second = input("Please enter your age again ")
# first will always contain a string
# second could contain any object and you can even
# type in a calculation and use "name" and "age" as
# you enter it at run time ...
print "You said you are",first
print "Then you said you are",second
примеры этого запуска:
Пример: 1
Prompt$ python yraw
Please enter your age 45
Please enter your age again 45
You said you are 45 Then you said you are 45
Пример: 2
Prompt$ python yraw
Please enter your age 45 + 7
Please enter your age again 45 + 7
You said you are 45 + 7 Then you said you are 52
Prompt$
Q. почему функция ввода вызывает eval?
а. Рассмотрим сценарий, в котором пользователь вводит выражение '45 + 7 'на входе, ввод даст правильный результат по сравнению с raw_input в python 2.x
Ответ 3
input
в значительной степени полезен только как строительный блок для интерактивной оболочки python. Вы, конечно, правы, что это удивительно, что это работает так, как оно есть, и скорее слишком специфично для того, чтобы быть встроенным, - я полагаю, поэтому он был удален из Python 3.
Ответ 4
raw_input лучше, он всегда возвращает вход пользователя без изменений.
И наоборот. Функция input() будет пытаться преобразовать объекты, которые вы вводите, как если бы они были кодом Python, и у него есть проблемы с безопасностью, поэтому вам следует избегать этого.
В реальной программе не используйте input(), проанализируйте свой ввод тем, что обрабатывает конкретный формат ввода, который вы ожидаете, а не оценивая ввод как код Python.