16

Estoy informandome con las funciones para interactuar con el usuario. Estoy con lo básico: raw_input() e input(). He leido que input() solo toma los datos intenger, que no acepta strings, y que para ello recurrimos a raw_input().

El problema está en que si almaceno un string en una variable con input() si que lo acepta y lo reconoce. Pero si intento hacer lo propio con raw_input() me da el siguiente error:

Traceback (most recent call last):
  File "lllll.py", line 9, in <module>
    raw_input()
NameError: name 'raw_input' is not defined

Trabajo con Python 3.5.2

FJSevilla
  • 55,603
  • 7
  • 35
  • 58
Jogofus
  • 765
  • 3
  • 15
  • 27

3 Answers3

31

El error se produce, como te han comentado, porque raw_input no existe en Python 3.X. Esto ha sido y seguirá siendo motivo de confusión porque las funciones input() no hacen lo mismo en Python 2 que en Python 3 a pesar de llamarse igual.

En Python 2.x existen ambas funciones, vamos a aclarar un poco que hace cada una:

Python 2.x:

  • raw_input() retorna una línea de la entrada del usuario tal cual, en crudo y retorna siempre una cadena de caracteres, un objeto str (ASCII) conteniendo lo introducido.

    >>> v = raw_input('Introduce algo: ')
    Introduce algo: 24
    >>> print v
    24
    

    Pero hay que recordar que la variable v no contiene un número, no es un int, es una cadena de caracteres (texto). Si intentamos operar como un entero:

    >>> v + 6
    

    Nos salta un error diciéndonos que no podemos sumar una cadena con un entero:

    Traceback (most recent call last):
      File "<pyshell#2>", line 1, in <module>
        v + 6
    TypeError: cannot concatenate 'str' and 'int' objects
    

    Para que sea un entero hay que convertirla haciendo un casting explícito (Python tiene tipado fuerte, no hace jamás un casting implícito para adaptar el tipo de la variable al contexto):

    >>> v = int(v)
    >>> v + 6
    30
    
  • input() espera que se le pasen expresiones Python válidas. Es decir, solo se le puede pasar código Python y la función lo evalúa y procesa como tal.

    >>> v = input('Ingresa algo que pueda evaluar: ')
    Ingresa algo que pueda evaluar: 2 + 5 * 3
    >>> print v
    17
    

    ¿Qué ha pasado aquí? Pues que input() ha cogido la expresión y como es código Python válido la ha evaluado y ha realizado las operaciones. Podríamos pensar que input() solo acepta núméricos pero esto es falso, no se porqué se ha extendido tanto, hasta el punto de generalizarse la idea de que input es para ingresar escalares y raw_input para cadena. Acepta cualquier expresión válida en Python:

    Concatenando dos cadenas:

    >>> v = input('Ingresa algo que pueda evaluar: ')
    Ingresa algo que pueda evaluar: 'hola ' + 'mundo'
    >>> print(v)
    'hola mundo'
    

    Creando una lista usando compresión de listas:

    >>> 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]
    

    Podemos pasar una cadena sin problemas, pero se le pasa una cadena usando las comillas, tal como declaramos un literal de cadena en el código:

    >>> v = input('Ingresa algo que pueda evaluar: ')
    Ingresa algo que pueda evaluar: "hola mundo"
    >>> print(v)
    hola mundo
    

    Otro error muy común es intentar usar input en Python 2 como se usa en Python 3, con la idea de asignar la cadena ingresada por el usuario a una 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
    

    Tenemos un error:

    NameError: name 'Jogofus' is not defined

    exactamente el mismo que si intentamos usar una variable que no está definida antes hacemos:

    >>> Jogofus + 5
    

    si hemos entendido que hace input en Python 2 no nos debe extrañar, al evaluar la cadena 'Jogofus' ingresada trata de buscar el nombre Jogofus en el espacio de nombres global (como si fuera el nombre de una variable, una función,clase, etc).

Python 3.x:

  • input() hace lo mismo que raw_input() en Python 2.x. Lee una línea de la entrada de la entrada estándar y la retorna en crudo en un objeto str (UTF-8). De hecho, es la misma función pero renombrada, la única diferencia es que en Python 2 str es ASCII mientra que en Python 3 es una cadena Unicode (UTF-8).

  • La antigua input() equivale a grandes rasgos a eval(), que toma una cadena de texto y la intenta evaluar como si fuera código Python válido. La diferencia es que en vez de leer la cadena desde la entrada estándar como hace input en Python 2, se le debe pasar como argumento:

    >>> v = eval(input('Ingresa algo que pueda evaluar: '))
    Ingresa algo que pueda evaluar: 'hola ' + 'mundo'
    >>> print(v)
    'hola mundo'
    

En definitiva, si usas Python 3.x solo existe input() y siempre retorna una cadena. Si usas Python 2.x raw_input hace lo mismo que input() en Python 3.x (acepta cualquier cadena y retorna siempre un objeto str) mientras que input() solo acepta expresiones que sean sintácticamente válidas en Python (en caso contrario producirá un error) y las evalúa después.

Te aconsejo que cuando mires documentación o tutoriales te fijes en que versión usan porque los cambios de la rama 2 a la 3 fueron importantes. Aquí tienes una lista de lo más significativo (en inglés):

https://docs.python.org/3/whatsnew/3.0.html

Advertencia: El uso de input (Python 2.x) o eval debe ser muy cuidadoso y nunca usarlas para captar entradas del usuario sin filtrar en aplicaciones sensibles (un servidor web por ejemplo). Recordemos que aceptan código Python y lo evalúan. Un usuario puede ingresar código dañino para el programa o el sistema, tanto de forma involuntaria como malintencionada. Un ejemplo, si tenemos importado el módulo os en el espacio de nombres donde se ejecuta input/eval, nada impide a un usuario si el script tiene privilegios suficientes ingresar os.system('rm -rf /') y mandar todos los archivos del sistema a mejor vida. exec, eval e input(Python 2) exponen a inyección de código malicioso, esto no significa que sean el demonio y que no deberían existir, son erramientas muy útiles y poderosas en muchos casos, pero hay que ser conscientes y consecuentes de su potencial y peligro.

FJSevilla
  • 55,603
  • 7
  • 35
  • 58
  • Perfectamente explicado. Es bueno recordar y recalcar que `input` en Python 3 devuelve una cadena en crudo (raw), de manera que si lees por ejemplo la siguiente cadena por teclado: `"salto\nlínea"`, la función `input` devolverá la cadena `"salto\\nlínea"` y no `"salto\nlínea"`. – Carlos A. Gómez Jun 29 '17 at 10:09
7

La función raw_input() fue renombrada a input() en Python 3.x

La antigua input() se puede emular con eval(input())

Alejandro Montilla
  • 1,060
  • 1
  • 10
  • 22
2

Para python2 existen 2 funciones input() y raw_input(), el primero es para valores numericos, en cambio el segundo es para cadenas de texto; pero esto cambia en python3, el raw_input() ha sido renombrado a input (), y el antiguo input() ha sido eliminado. Por lo tanto si usas python 3 debes usar input() en vez de raw_input()