Python 2 vs Python 3
How to overcome some of the differences between major versions with the use of __future__
print is a _statement _

**In Python 3: **
print is a function

Functions need parenthesis around the arguments we're passing them
**In Python 2: **
If we were to wrap our string in parenthesis it would print without issues... But...

It would also print without issues... But..
Because 'hello' in Python 2 would be a **tuple **of a single object .
Collection or two (2) or more objects. Tuples are represented by using parenthesis around the objects that comprise them .
**In Python 2: **will just convert this back to a string

It converts it to a string because it is a single object tuple
If we were to add a second object, it would be kept as a tuple after hitting enter

This time the tuple was not transformed to a string
This is not the behavior that would be observed In Python 3 :

In Python 3 print is a function and needs to have arguments passed in ()
Since print is a function in Python 3 , the arguments would be passed to print() function and they would be printed as expected

print is a function in Python 3 and arguments are passed to print()
If we want our scripts to run in Python 2 and in Python 3 , we would want _common operations _such as print to run in both versions.
A solution to the problem stated above is given by the use of futures. "futures" make Python 2 behave like Python 3 for certain functions.
feature | optional in | mandatory | effect |
---|---|---|---|
nested_scopes | 2.1.0b1 | 2.2 | |
generators | 2.2.0a1 | 2.3 | |
division | 2.2.0a2 | 3.0 | |
absolute_import | 2.5.0a1 | 3.0 | |
with_statement | 2.5.0a1 | 2.6 | |
print_function | 2.6.0a2 | 3.0 | |
unicode_literals | 2.6.0a2 | 3.0 | |
generator_stop | 3.5.0b1 | 3.7 | |
annotations | 3.7.0b1 | 4.0 |
In this case _**print **is _
First, we import it from __future__:
from __future__ import print_function

print function behaves like in Python 3
Now if after importing print_function from __future__ we attempted to use the print function, it will never behave like a statement again which is the native Python 2 behavior

Just as in Python 3, print"hello", errors out. See below

_from __future__ import print_function _it would just ignore it.

Nothing changes in the behavior of Python 3 by importing the print function from __future__
Division
In Python 2, floor division drops the remainder and returns only a whole number.

Python 2 thinks that you are dividing an integer by an integer, and that you probably want and integer back and drops the remainder.
If, instead, we were to provide one of the numbers as a float, the returned result would be a float too.

A floating point number aka "float", is a number that includes decimal portion.
Again, if we wanted to have Python 2 behave like Python 3, we may import the **division __future__ **module

We import division from __future__
After importing the **division module from __future__ **and performing a division that would yield a remainder we can observe that **Python 2 **is outputting the expected remainder
Additionally, we can observe that if we escape the / (backslash) we may receive the output without the remainder again.

we may use double slash '//' and receive the truncated remainder output
Why would we want to do this? Convenience, sometimes you would want to get one output or the other
To provide our Python 2 scripts with some forward compatibility, we may use the following line in our scripts:
from __future__ import absolute_import, division, print_function

If I wanted to get input from an user, assigning it to variable X:
We may prompt the user to type something:

we would get a name error saying that "hello" is not defined
The error is letting us know that that python does not have any objects named "hello"
If now, in contrast we do create an object called hello and assign it the value 242

The value we initialized (242) and assigned to hello is now "x"
This time we get no error because hello has been previously defined
It would not be uncommon to think that x = hello right?

No. Why? Because it assigned to X the value of the hello object we had previously created
As you can imagine this behavior is not useful.
The raw_input function helps us in this case. Fixes the issue because using raw input, when I type something
and I check the value of x, it is being assigned to what I typed.

This is typically what you want.
In Python 3:

The behavior raw_input would have in Python 2 is default in Python 3
In Python 3: the functions of raw_input are performed by input. raw_input does not exist in Python 3.

raw_input does not exist in Python 3.
We may leverage the fact that raw_input creates an error in python 3 and we can tell it to try raw input and catch the exception and NameError, use input function instead.

Attempt to use raw_input, otherwise, in case of NameError use input()
from __future__ import absolute_import, division, print_function
from pip._vendor.distlib.compat import raw_input
def get_input(prompt=''):
try:
line = raw_input(prompt)
except NameError:
x = input(prompt)
return line
x = get_input('Type : ')
print(x)
Last modified 1yr ago