Question:
I am informing myself with the functions to interact with the user. I'm with the basics: raw_input()
and input()
. I have read that input()
only takes the intenger data, that it does not accept strings, and that for this we resort to raw_input()
.
The problem is that if I store a string in a variable with input()
it accepts and recognizes it. But if I try to do the same with raw_input()
it gives me the following error:
Traceback (most recent call last): File "lllll.py", line 9, in <module> raw_input() NameError: name 'raw_input' is not defined
I work with Python 3.5.2
Answer:
The error occurs, as you have been told, because raw_input
does not exist in Python 3.X
This has been and will continue to be a source of confusion because the input()
functions do not do the same in Python 2
as they do in Python 3
despite being called the same.
In Python 2.x
there are both functions, let's clarify a bit what each one does:
Python 2.x :
-
raw_input()
returns a line of user input as is, raw and always returns a string of characters , astr
(ASCII) object containing what was entered.>>> v = raw_input('Introduce algo: ') Introduce algo: 24 >>> print v 24
But we must remember that the variable
v
does not contain a number, it is not anint
, it is a character string (text). If we try to operate as an integer:>>> v + 6
We get an error telling us that we cannot add a string with an integer:
Traceback (most recent call last): File "<pyshell#2>", line 1, in <module> v + 6 TypeError: cannot concatenate 'str' and 'int' objects
In order for it to be an integer, it must be converted by doing an explicit casting (Python has strong typing, it never does an implicit casting to adapt the type of the variable to the context):
>>> v = int(v) >>> v + 6 30
-
input()
expects valid Python expressions to be passed to it . That is, only Python code can be passed to it and the function evaluates and processes it as such.>>> v = input('Ingresa algo que pueda evaluar: ') Ingresa algo que pueda evaluar: 2 + 5 * 3 >>> print v 17
What happened here? Well,
input()
has taken the expression and as it is valid Python code it has evaluated it and performed the operations. We could think thatinput()
only accepts numerics but this is false, I don't know why it has spread so much, to the point of generalizing the idea thatinput
is for entering scalars andraw_input
for string. Accept any valid Python expression:Concatenating two strings:
>>> v = input('Ingresa algo que pueda evaluar: ') Ingresa algo que pueda evaluar: 'hola ' + 'mundo' >>> print(v) 'hola mundo'
Creating a list using list compression:
>>> v = input('Ingresa algo que pueda evaluar: ') Ingresa algo que pueda evaluar: [n *2 for n in range (10)] >>> print(v) [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
We can pass a string without problems, but a string is passed to it using the quotes, just as we declared a string literal in the code:
>>> v = input('Ingresa algo que pueda evaluar: ') Ingresa algo que pueda evaluar: "hola mundo" >>> print(v) hola mundo
Another very common mistake is trying to use
input
in Python 2 as used in Python 3, with the idea of assigning the string entered by the user to a variable:>>> nombre = input('Ingrese su nombre: ') Ingrese su nombre: Jogofus Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'Jogofus' is not defined
We have an error:
NameError: name 'Jogofus' is not defined
exactly the same as if we try to use a variable that is not defined before we do:
>>> Jogofus + 5
If we have understood that it does
input
in Python 2 it should not surprise us, when evaluating the entered 'Jogofus' string it tries to find the nameJogofus
in the global namespace (as if it were the name of a variable, a function, class, etc. ).
Python 3.x:
-
input()
does the same asraw_input()
inPython 2.x
Reads a line from the standard input input and returns it raw in astr
(UTF-8) object. In fact, it is the same function but renamed, the only difference is that in Python 2str
is ASCII while in Python 3 it is a Unicode string (UTF-8). -
The old
input()
is roughly equivalent toeval()
, which takes a text string and tries to evaluate it as valid Python code. The difference is that instead of reading the string from standardinput
asinput
does in Python 2, it must be passed as an argument:>>> v = eval(input('Ingresa algo que pueda evaluar: ')) Ingresa algo que pueda evaluar: 'hola ' + 'mundo' >>> print(v) 'hola mundo'
In short, if you use Python 3.x
there is only input()
and it always returns a string. If you use Python 2.x
raw_input
does the same as input()
in Python 3.x
(accepts any string and always returns a str
object) while input()
only accepts expressions that are syntactically valid in Python (otherwise it will produce a error) and evaluates them later.
I advise you that when you look at documentation or tutorials you look at which version they use because the changes from branch 2 to 3 were important. Here is a list of the most significant:
https://docs.python.org/3/whatsnew/3.0.html
Warning: The use of
input
(Python 2.x) oreval
should be very careful and never use them to catch unfiltered user input in sensitive applications (a web server for example). Remember that they accept Python code and evaluate it. A user can enter code that is harmful to the program or the system, both inadvertently and maliciously. An example, if we have imported theos
module in the namespace whereinput
/eval
is executed, nothing prevents a user if the script has sufficient privileges to enteros.system('rm -rf /')
and send all the files from the system to better life.exec
,eval
andinput
(Python 2) expose you to injection of malicious code , this does not mean that they are the demon and that they should not exist, they are very useful and powerful tools in many cases, but you have to be aware and consistent of their potential and danger .