48

I would like to set a user prompt with the following question:

save_flag is not set to 1; data will not be saved. Press enter to continue.

input() works in python3 but not python2. raw_input() works in python2 but not python3. Is there a way to do this so that the code is compatible with both python 2 and python 3?

everton
  • 7,579
  • 2
  • 29
  • 42
218
  • 1,754
  • 7
  • 27
  • 38

6 Answers6

63

Bind raw_input to input in Python 2:

try:
    input = raw_input
except NameError:
    pass

Now input will return a string in Python 2 as well.


If you're using six to write 2/3 compatible code then six.input() there points to raw_input() in Python 2 and input() in Python 3.

Alex Taylor
  • 8,343
  • 4
  • 25
  • 40
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • 3
    Pylint on Python 2.7 doesn't like it: `Redefining built-in 'input' (redefined-builtin)` – Hugo Dec 18 '14 at 18:51
  • 4
    Argh... Pylint is both a blessing and a curse. A blessing for n00bs to Python to help guide them in writing Python code; a curse to advanced Python charmers for slapping them for perfectly valid code. I would argue that Pylint is wrong in this case and it sucks to have to uglify your code with a `# pylint: disable` comment just to make some tool happy. – OozeMeister Aug 03 '16 at 13:16
  • 5
    When I try to use this I get `UnboundLocalError: local variable 'input' referenced before assignment` when using `input` afterwards, even when it's running Python 3 – Pro Q Jan 24 '17 at 06:51
  • 4
    @ProQ That's because you're doing this inside a function / class. You need to do it outside, otherwise Python will think you are declaring a local variable, and it will not have a value if there is a NameError. – Artyer Apr 05 '17 at 16:46
  • The path in `six` is now `six.moves.input`. – bgusach Oct 05 '21 at 10:07
15

I think the best way to do this is

import six

six.moves.input()

...it'll work across 2 and 3.

joedborg
  • 17,651
  • 32
  • 84
  • 118
6

Update: This method only works if you have future installed and the answers above are much better and more generalizable.

From this cheatsheet there is another method that looks cleaner:

# Python 2 and 3:
from builtins import input
emschorsch
  • 1,619
  • 3
  • 19
  • 33
  • 7
    In Python 2: `ImportError: No module named builtins` – OozeMeister Aug 03 '16 at 13:12
  • 6
    ahh I had the future package installed and didn't realize it. – emschorsch Aug 04 '16 at 00:15
  • 1
    This answer is what I do, install the future package and then import from future and also use `from builtins import *` in every script. – matth Apr 10 '17 at 09:12
  • 2
    most modern python training courses provide this code to overcome this problem: `if hasattr(__builtins__, 'raw_input'): input = raw_input` (2nd line is indented under first). The answer provided here did not work on an Anaconda distribution of iPython 2.7 and I see others reporting issues with this solution as well. This answer should be deleted so people do not try to use it and run into trouble. – TMWP May 18 '17 at 16:45
  • Oddly enough, I've had issues with `EOFError` using this method. `from six.moves import input` seems to work better for me – aiguofer Nov 09 '18 at 02:36
2

This is because, In python 2, raw_input() accepts everything given to stdin, as a string, where as input() preserves the data type of the given argument (i.e. if the given argument is of type int, then it will remain as int only, but won't be converted to string as in case of raw_input()). That is basically, when input() is used, it takes the arguments provided in stdin as string, and evaluates the same. And this evaluation converts the argument to corresponding type.

# Python 2.7.6
>>> a = raw_input("enter :- ")
enter :- 3
>>> type(a)     # raw_input() converts your int to string
<type 'str'>
>>> a = input("enter :- ")
enter :- 3
>>> type(a)    # input() preserves the original type, no conversion     
<type 'int'> 
>>>

Therefore, while using input() in Python 2, user has to be careful while passing the arguments. If you are passing a string, you need to pass it with quote ( since python recognizes characters inside quote as string). Else NameError will be thrown.

 >>> a = input("enter name :- ")
 enter name :- Derrick
 Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<string>", line 1, in <module>
 NameError: name 'Derrick' is not defined
 >>> a = input("enter name :- ")
 enter name :- 'Derrick'
 >>> a
 'Derrick'

Whereas, if using raw_input(), you need not worry about the data type while passing the argument as everything it accepts as a string. But yes, inside your code you need to take care of appropriate type conversion.

To avoid this extra care needed for input() in Python 2, it has been removed in Python 3. And raw_input() has been renamed to input() in Python 3. The functionality of input() from Python 2 is no more in Python 3. input() in Python 3 serves what raw_input() was serving in Python 2.

This post might be helpful for a detailed understanding.

Pabitra Pati
  • 457
  • 4
  • 12
  • -1 although it is a nice explanation, it completely misses the question: *Is there a way to do this so that the code is compatible with both python 2 and python 3?*. The OP knows about the differences and is interested in a solution to the problem, not the explanation of it. Btw, the functionality of py2 input can be easily recovered with eval(input()) in py3, which makes your last sentences about the functionality, that is no more, obsolet. Yes, there is no single command, but a very simple recovery. – Mayou36 Jul 24 '17 at 08:28
  • DO NOT use `eval` to replicate Py2 behaviour. That is not the equivalent of `input` in Py2. Use `ast.literal_eval`. – DylanYoung Jan 24 '20 at 15:46
1

Explicitly load the function:

from builtins import input

Then you can use input() in python2 as well as python3.

You may have to install the dependency:

pip install future

Alex
  • 12,078
  • 6
  • 64
  • 74
1

You can write your code in either python2 and use futurize or in python3 and use pasteurize. This removes the complexity of thinking about compatible code and guarantees good practices.

Regarding this specific question

from builtins import input

Is exactly what the above scripts produce.

gbonetti
  • 1,334
  • 17
  • 18