32

I currently teach first year university students python, and I was surprised to learn that the seemingly innocuous input function, that some of my students had decided to use (and were confused by the odd behaviour), was hiding a call to eval behind it.

So my question is, why does the input function call eval, and what would this ever be useful for that it wouldn't be safer to do with raw_input? I understand that this has been changed in Python 3, but it seems like an unusual design decision in the first place.

Python 2.x input function documentation

Chris Morgan
  • 86,207
  • 24
  • 208
  • 215
luketparkinson
  • 322
  • 3
  • 7
  • 8
    It's useful for code-golf – John La Rooy Oct 10 '11 at 06:19
  • To answer the “why” – Python's first REPL might have been `while 1: print input()`. I bet at that ancient time, supporting good programming practices was not as high on Python's list of priorities as it is now. Python 3's `while True: print(eval(input()))` might even seem more confusing – all those nested parentheses! – Petr Viktorin Oct 10 '11 at 14:24

4 Answers4

38

Is it ever useful to use Python 2's input over raw_input?

No.


input() evaluates the code the user gives it. It puts the full power of Python in the hands of the user. With generator expressions/list comprehensions, __import__, and the if/else operators, literally anything Python can do can be achieved with a single expression. Malicious users can use input() to remove files (__import__('os').remove('precious_file')), monkeypatch the rest of the program (setattr(__import__('__main__'), 'function', lambda:42)), ... anything.

A normal user won't need to use all the advanced functionality. If you don't need expressions, use ast.literal_eval(raw_input()) – the literal_eval function is safe.

If you're writing for advanced users, give them a better way to input code. Plugins, user modules, etc. – something with the full Python syntax, not just the functionality.

If you're absolutely sure you know what you're doing, say eval(raw_input()). The eval screams "I'm dangerous!" to the trained eye. But, odds are you won't ever need this.


input() was one of the old design mistakes that Python 3 is solving.

Petr Viktorin
  • 65,510
  • 9
  • 81
  • 81
  • This is what I was thinking, even if you wanted `input`'s functionality, if you did `eval(raw_input())` then you would at least see that it was dangerous. And there's not really a good reason to use it otherwise. Thanks! – luketparkinson Oct 10 '11 at 12:24
7

Python Input function returns an object that's the result of evaluating the expression. raw_input function returns a string

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

examples of that running:

Example: 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

Example: 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. why does the input function call eval?

A. Consider the scenario where user inputs an expression '45 + 7' in input, input will give correct result as compared to raw_input in python 2.x

tobyodavies
  • 27,347
  • 5
  • 42
  • 57
avasal
  • 14,350
  • 4
  • 31
  • 47
  • 1
    alternatively they could enter `quit()` which is rather dangerous if you are part way through a critical section of code... – tobyodavies Oct 10 '11 at 06:15
  • 8
    Or they could input `__import__('os').remove('precious_file')` which is rather dangerous *anywhere*. [`ast.literal_eval(raw_input())`](http://docs.python.org/library/ast.html#ast.literal_eval) is a much better choice in practically all situations. No wonder [Python 3's input()](http://docs.python.org/py3k/library/functions.html#input) works like 2's raw_input(). – Petr Viktorin Oct 10 '11 at 09:26
  • 7
    I disagree with this answer. Why do you consider the "correct result" for the input to be 52? I would consider the correct result to be "please enter a number." There is no good reason for a program that asks for a number to compute the result of a Python expression the user may give. Not only is this absurd behaviour, but also a serious security risk as Petr pointed out. The question was "is input useful" and the answer is "no". – mgiuca Oct 10 '11 at 10:53
  • This is not helpful at all, if you want to build a calculator then do it safely through a parser, such as described here https://stackoverflow.com/a/9558001/6260170 – Chris_Rands Sep 06 '17 at 16:33
4

input is pretty much only useful as a building block for an interactive python shell. You're certainly right that it's surprising it works the way it does, and is rather too purpose-specific to be a builtin - which I presume is why it got removed from Python 3.

Nick Johnson
  • 100,655
  • 16
  • 128
  • 198
2

raw_input is better, It always returns the input of the user without changes. Conversely The input() function will try to convert things you enter as if they were Python code, and it has security problems so you should avoid it.

In real program don't use input(), Parse your input with something that handles the specific input format you're expecting, not by evaluating the input as Python code.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219