raw_input("") has been eliminated from python 3.2 - python

I have tried a lot to run raw_input("") on the python console but that gives an error. Moreover I watch some videos that might have been made on old python. so input("") is the only method and why raw_input("") is discarded in the new version is there any reason ?

raw_input() was renamed to input() in Python v3.x
The old input() is gone, but you can emulate it with eval(input())
What's new in Python 3 will mention this (and more):
PEP 3111: raw_input() was renamed to input(). That is, the new input()
function reads a line from sys.stdin and returns it with the trailing
newline stripped. It raises EOFError if the input is terminated
prematurely. To get the old behavior of input(), use eval(input()).

Python 3.x's input is python 2.x's raw_input. The function has just been renamed since the old 2.x input was broken by design and therefore eliminated in 3.x.

The reason for this is that the old input() function tries to convert things you type as if it's python code. It generates lot of security issues, that's mainly why it was discarded for the raw_input instead but renamed input() because, well, you know, we programmers are a little bit lazy and typing input() instead of raw_input takes 4 less characters so...

Related

Getting input from user without using "input" function [duplicate]

I was wondering if anyone has suggestions for writing a backwards-compatible input() call for retrieving a filepath?
In Python 2.x, raw_input worked fine for input like /path/to/file. Using input works fine in this case for 3.x, but complains in 2.x because of the eval behavior.
One solution is to check the version of Python and, based on the version, map either input or raw_input to a new function:
if sys.version_info[0] >= 3:
get_input = input
else:
get_input = raw_input
I'm sure there is a better way to do this though. Anyone have any suggestions?
Since the Python 2.x version of input() is essentially useless, you can simply overwrite it by raw_input:
try:
input = raw_input
except NameError:
pass
In general, I would not try to aim at code that works with both, Python 2.x and 3.x, but rather write your code in a way that it works on 2.x and you get a working 3.x version by using the 2to3 script.
This code is taught in many Python education and training programs now.
Usually taught together:
from __future__ import print_function
if hasattr(__builtins__, 'raw_input'):
input = raw_input
First line: imports the Python 3.x print() function into Python 2.7 so print() behaves the same under both versions of Python. If this breaks your code due to older print "some content" calls, you can leave this line off.
Second and third lines: sets Python 2.7 raw_input() to input() so input() can be used under both versions of Python without problems. This can be used all by itself if this is the only compatibility fix you wish to include in your code.
There are more from __future__ imports available on the Python.org site for other language compatibility issues. There is also a library called "six" that can be looked up for compatibility solutions when dealing with other issues.
The way you are handling it is just fine. There are probably more similar ways using the sys module, but just in keep in mind that if you are program is doing something more than trivial with strings and files, it is better to have two versions of your program instead of having a backwards compatible python3 program.
You could import the function:
from builtins import input
Unfortunately though this method requires an external dependency via pip install future

Why does Python 3 code run on Python 2, at all?

I created a small shopping list program designed to run on Python 3. I assumed my Mac was running Python 3 and tried to run the file. It seemed to work well as long as I surrounded my input strings with quotation marks, otherwise I got a NameError. This is not needed in Python 3.
Why did the code run at all? I know that functions such as print() are written differently in Python 2 so why didn't it fail from the get-go?
# List Creation
shopping_list = []
# Help
def show_help():
print("""
Add items to the list when promted.
To end the list type 'DONE'.
To view the list type 'SHOW'.
To view this help prompt, type 'HELP'.
""")
show_help()
# View
def view_list():
print(shopping_list)
while True:
new_item = input("> ")
if new_item.upper() == 'DONE':
break
elif new_item.upper() == 'HELP':
show_help()
continue
elif new_item.upper() == 'SHOW':
view_list()
continue
shopping_list.append(new_item)
print(shopping_list)
A lot of Python 3 code runs in Python 2 because Python was specifically designed to make that true.
print is a bit of a special case—simple prints of a single variable do the same thing in both languages, but more complex prints may not. How does this work?
In Python 3, print(shopping_list) is a call to the print function with a single argument, shopping_list.
In Python 2, print(shopping_list) is a print statement with one printable, the value (shopping_list), which is of course the same value as shopping_list. So you get the same thing.
Of course that isn't true as soon as you print(x, y) (which works, but prints a single 2-tuple value rather than two values in Python 2) or print(x, file=sys.stderr) (which is an error in Python 2).
input is another special case. This one wasn't designed to be compatible, you're just getting lucky here. Or maybe unlucky.
In Python 2, input() does eval(raw_input())—that is, it takes what you type and tries to evaluate it as Python source.
In Python 3, input() does what raw_input() did in Python 2—that is, it just returns a string.
So, the code sort of works in both, although you have to type "DONE" instead of just DONE in Python 2—just like you have to type "DONE" in your source code. Plus, of course, you can type __import__('os').system('rm -rf /') in Python 2 and make yourself very sad. (This is why Python 2's input doesn't exist in Python 3.)
If you're asking why Python 3 was designed this way:
Once it was decided that some backward incompatibility was required in order to fix two decades of backlogged problems, there was a discussion about whether "Python 3000" should be intentionally incompatible to noisily break everything, or as compatible as possible (but no more so) to make migration easier.
The team decided on the latter. That included making some changes to Python 2.6 to make it easier to eventually migrate to 3.x, and some design decisions in Python 3.0 that were only made to make migration from 2.6 easier.
Once Python 3 got out into the wild, that turned out to be the right choice. To almost everyone's surprise, it was actually easier to write "dual-version" code (with the help of adapter libraries like six) than to write code that could be auto-transformed via 2to3 and 3to2.
So they went even farther. Python 2.7 added a few features designed just for dual-version code, and they've continued to add things like the u string literal prefix (which does nothing in Python 3, but it's a way of making sure you have Unicode strings whether you run in 2.7 or 3.4) and bytes.__mod__ (which allows Python 2 %-formatting code to continue to work in Python 3 in cases where you've deliberately chosen to keep things in bytes—e.g., parsing HTTP, where all you know is that it's some ASCII-compatible charset until you reach the charset header).
By the way, one of those "forward-compatibility" changes to Python 2 was the addition of from __future__ import print_function, which gives you Python 3-style print.
With regards to print, Python3 made it a proper function, so you must call it with parentheses. In Python2, those parentheses are interpreted as "grouping" parenthesis rather than the start of a function call, so it makes no difference.
Python2: print (1 + 2) means, evaluate the expression (1 + 2) -> print 3
Python3: print (1 + 2) means evaluate the expression 1 + 2 and pass the result into the function print -> print(3)
It ran because it is perfectly valid Python 2 code. However, input in Python 2 tries to evaluate the string that is input as a Python expression; the equivalent in Python 3 would be eval(input("> ")). Python 2 should always use raw_input, and Python 3 enforces that by getting rid of the old input behavior and renaming raw_input to input.
As for print, each of the items following the print keyword is an expression, and a valid expression can be wrapped in parentheses. print('hello') just prints the result of the expression ('hello'), which is equivalent to the unparenthesized string 'hello'; hence, print('hello') and print 'hello' are equivalent.
Note that print 'hello', and print('hello',), however, would not be equivalent; the former prints the string hello with no line ending, while the latter prints the single-element tuple (hello,). In Python 3, print('hello',) and print('hello') would be the same, since an argument list to a function call is allowed to have a trailing comma that gets ignored.
You are not leveraging on the improvements of Python 3.
Hence it works (except with print) in Python 2

What was the rationale behind creating input() in Python 2?

In Python 2, there were two ways of getting input. raw_input() and input(), which was a wrapper around eval(raw_input()). In Python 3 however, input() replaced raw_input() and the old meaing of input() was deprecated. This is documented in What's new in Python 3:
PEP 3111: raw_input() was renamed to input(). That is, the new input() function reads a line from sys.stdin and returns it with the trailing newline stripped. It raises EOFError if the input is terminated prematurely. To get the old behavior of input(), use eval(input()).
But why exactly was input() around in Python 2 in the first place? What was the rationale for having user input that was evaluated as literal Python 2 code? This is what the Python 2 documentation had to say:
[input() is] Equivalent to eval(raw_input(prompt)).
This function does not catch user errors. If the input is not syntactically valid, a SyntaxError will be raised. Other exceptions may be raised if there is an error during evaluation.
If the readline module was loaded, then input() will use it to provide elaborate line editing and history features.
Consider using the raw_input() function for general input from users.
Notice the part in bold (which I emphasized). What exactly does this mean? I looked over the documentation for the readline module and found a few things. The only real relevant bit I found, however, was this:
Settings made using this module affect the behavior of both the interpreter’s interactive prompt and the prompts offered by the raw_input() and input() built-in functions.
Which doesn't really help explain why input() was created or needed in the first place, though.
Needless to say, using eval(any_user_input()) is very dangerous security wise, can cause debugging difficulties, and, from what I've read, is slow. So why did they create input() in Python 2 in the first place? Were the developers unaware at the time of the downfalls of input()?
References:
Is using eval in Python a bad practice?
eval(input()) in python 2to3
What’s New In Python 3.0
Python 2.7.12 documentation
First of all, probably the only person who can answer this question decisively is the BDFL.
input can be useful in programs that are meant to be used by a programmer, so that they can enter complex structures, like {'foo': 42}, or even expressions, but less so in programs intended to be used by an unskilled user.
From the SCM history we can see that both input and raw_input were present in 1990; or pre-0.9, when Python was in its infancy - back then exec was a function, and int('42') would have thrown an exception. Most notably, eval was already present as well, so one could have used eval(raw_input()) even back then to get much of the same effect.
Back then there was no Zen of Python yet, and the "only one obvious way" wasn't as much a guiding principle, so this could have been an oversight.
And both raw_input and input remained. During the history of Python, the backwards-compatibility was a guiding principle, so input was unchanged until backwards-incompatible Python 3 was released.
As for the bolded part about readline module: if you import readline, then you can use arrow keys to move cursor keys around on the input() line, and configurable bindings; if readline is not imported in the program, then no such behaviour exists.
Again, this wouldn't have been the reason for input existing in the first place; back in 1990 Python didn't support such editing at all, regardless of whether input or raw_input was used.
For what it worths, input builtin was there in a first available Python version (0.9.1), it is from 1991. I can imagine Python 2.x had it for backwards compatibility with Python 1.x, and Python 1.x had it for backwards compatibility with 0.x.
Say no to 0.x -> 1.x and 1.x -> 2.x porting issues!

Python file opening with NameError: name not defined

So when I directly double click my Base64 encoder/decoder script, it opens and closes with an error, I luckily did print screen before it closed, and this is the error:
What does that even mean? The program runs perfectly in the IDLE, with no errors.
This is my code, take a look!
http://gyazo.com/69a31e3d63987bb44f4d8d69e01423bc.png
The error seems to be your use of input which is attempting to eval the string that you put in. This is the behavior of input on python2.x. You probably want to use raw_input. On python3.x, raw_input was renamed input and the previous input function was removed.
One trick that I tend to use in situations like these where I need to support python2.x and python3.x in the same script is to use raw_input everywhere and then at the top of your script do something like:
try:
raw_input # No error on python2.x
except NameError:
raw_input = input # python3.x

Backwards-compatible input calls in Python

I was wondering if anyone has suggestions for writing a backwards-compatible input() call for retrieving a filepath?
In Python 2.x, raw_input worked fine for input like /path/to/file. Using input works fine in this case for 3.x, but complains in 2.x because of the eval behavior.
One solution is to check the version of Python and, based on the version, map either input or raw_input to a new function:
if sys.version_info[0] >= 3:
get_input = input
else:
get_input = raw_input
I'm sure there is a better way to do this though. Anyone have any suggestions?
Since the Python 2.x version of input() is essentially useless, you can simply overwrite it by raw_input:
try:
input = raw_input
except NameError:
pass
In general, I would not try to aim at code that works with both, Python 2.x and 3.x, but rather write your code in a way that it works on 2.x and you get a working 3.x version by using the 2to3 script.
This code is taught in many Python education and training programs now.
Usually taught together:
from __future__ import print_function
if hasattr(__builtins__, 'raw_input'):
input = raw_input
First line: imports the Python 3.x print() function into Python 2.7 so print() behaves the same under both versions of Python. If this breaks your code due to older print "some content" calls, you can leave this line off.
Second and third lines: sets Python 2.7 raw_input() to input() so input() can be used under both versions of Python without problems. This can be used all by itself if this is the only compatibility fix you wish to include in your code.
There are more from __future__ imports available on the Python.org site for other language compatibility issues. There is also a library called "six" that can be looked up for compatibility solutions when dealing with other issues.
The way you are handling it is just fine. There are probably more similar ways using the sys module, but just in keep in mind that if you are program is doing something more than trivial with strings and files, it is better to have two versions of your program instead of having a backwards compatible python3 program.
You could import the function:
from builtins import input
Unfortunately though this method requires an external dependency via pip install future

Categories