Many beginners in Python will ask: Which version of Python should I learn? For this question, my answer is usually "first choose the Python tutorial that best suits you, which version of Python you use in the tutorial, and you use that version." Study the difference between the different versions. "
But if you want to develop a new project in Python, how do you choose the Python version? I can responsibly say that most python libraries support both Python 2.7.x and 3.x versions, so whichever version you choose is possible. But in order to avoid some common pitfalls in some versions when using Python, or to port a Python project, it is still necessary to understand the main differences between Python's two common versions.
Directory
Using the __future__ module
Print function
Integer division
Unicode
Xrange
Triggering an exception
Handling Exceptions
Next () function and the. Next () method
For loop variables and global namespace leaks
Compare unordered types
Parsing input using input ()
Returns an iterative object instead of a list
More articles on Python 2 and Python 3
__FUTURE__ Module
[Back to catalogue]
Python 3.x introduces some keywords and features that are incompatible with Python 2, and in Python 2, you can import these new content through the built-in __future__ module. If you want code written in a Python 2 environment to run in Python 3.x, we recommend using the __FUTURE__ module. For example, if you want to have the integer division behavior of Python 3.x in Python 2, you can import the corresponding module by using the following statement.
From FutureImport Division
The following table lists the other features that can be imported in __future__:
Feature optional version force version effect
Nested_scopes 2.1.0b1 2.2 PEP 227:
Statically Nested Scopes
Generators 2.2.0A1 2.3 PEP 255:
Simple generators
Division 2.2.0A2 3.0 PEP 238:
Changing the Division Operator
Absolute_import 2.5.0A1 3.0 PEP 328:
Imports:multi-line and Absolute/relative
With_statement 2.5.0a1 2.6 PEP 343:
The "with" Statement
Print_function 2.6.0A2 3.0 PEP 3105:
Make Print a function
Unicode_literals 2.6.0A2 3.0 PEP 3112:
Bytes literals in Python 3000
(Source: https://docs.python.org/2/library/future.html)
Example:
From platform import python_version
Print function
[Back to catalogue]
Although the print syntax is a small change in Python 3 and should be well known, it is worth mentioning that the print statement in Python 2 is replaced by the print () function in Python 3, which means that the Python 3 must enclose the object that needs to be output in parentheses.
It is also possible to use extra parentheses in Python 2. However, when you want to call the print function without parentheses in Python 3 in the form of Python2, the syntaxerror is triggered.
Python 2
print ' Python ', python_version ()
print ' Hello, world! '
Print (' Hello, world! ')
Print "text",; print ' Print more text in the same line '
Python 2.7.6
Hello, world!.
Hello, world!.
Text print more text on the same line
Python 3
Print (' Python ', Python_version ())
Print (' Hello, world! ')
Print ("Some text,", end= "")
Print (' Print more text on the same line ')
Python 3.4.1
Hello, world!.
Some text, print more text in the same line
print ' Hello, world! '
File " ", Line 1
print ' Hello, world! '
^
Syntaxerror:invalid syntax
Attention:
In Python, it is normal to output "Hello world" with no parentheses. However, if you are outputting multiple objects at the same time in parentheses, a tuple is created because in Python 2, print is a statement, not a function call.
print ' Python ', python_version ()
Print (' A ', ' B ')
print ' A ', ' B '
Python 2.7.7
(' A ', ' B ')
A b
Integer division
[Back to catalogue]
Since it is often overlooked that Python 3 changes in integer division (which does not trigger syntax error), you need to pay particular attention to this change when porting code or executing Python 3 code in Python 2.
So, I'm going to try to use float (3)/2 or 3/2.0 instead of 3/2 in the Python 3 script to avoid the error that code might cause in a Python 2 environment (or, in contrast, in a Python 2 script using the From FutureImport Division to use the division of Python 3).
Python 2
print ' Python ', python_version ()
print ' 3/2 = ', 3/2
print ' 3//2 = ', 3//2
print ' 3/2.0 = ', 3/2.0
print ' 3//2.0 = ', 3//2.0
Python 2.7.6
3/2 = 1
3//2 = 1
3/2.0 = 1.5
3//2.0 = 1.0
Python 3
Print (' Python ', Python_version ())
Print (' 3/2 = ', 3/2)
Print (' 3//2 = ', 3//2)
Print (' 3/2.0 = ', 3/2.0)
Print (' 3//2.0 = ', 3//2.0)
Python 3.4.1
3/2 = 1.5
3//2 = 1
3/2.0 = 1.5
3//2.0 = 1.0
Unicode
[Back to catalogue]
Python 2 has an ASCII-based STR () type, which can be converted to a Unicode type by a separate Unicode () function, but without a byte type.
In Python 3, there is finally a Unicode (Utf-8) string, and two byte classes: bytes and bytearrays.
Python 2
print ' Python ', python_version ()
Python 2.7.6
Print type (Unicode (' This was like a python3 str type '))
<type ' Unicode ' >
Print type (b ' byte type does not exist ')
<type ' str ' >
print ' They is really ' + B ' the same '
They is really the same
Print type (ByteArray (b ' ByteArray oddly does exist though '))
<type ' ByteArray ' >
Python 3
Print (' Python ', Python_version ())
Print (' Strings is now utf-8 u03bcnicou0394é! ')
Python 3.4.1
Strings is now utf-8μnicoδé!
Print (' Python ', python_version (), end= "")
Print (' Have ', type (b ' bytes for storing data ')
Python 3.4.1 has <class ' bytes ' >
Print (' and Python ', python_version (), end= "")
Print (' also has ', type (ByteArray (b ' bytearrays ')))
And Python 3.4.1 also has <class ' ByteArray ' >
' Note that we cannot add a string ' + B ' bytes for data '
---------------------------------------------------------------------------
TypeError Traceback (most recent)
in ()
----> 1 ' Note that we cannot add a string ' + B ' bytes for data '
Typeerror:can ' t convert ' bytes ' object to str implicitly
Xrange
[Back to catalogue]
In Python 2.x, you often create an iterative object with Xrange (), which usually appears in the For loop or in List/collection/dictionary derivation.
This behavior is very similar to the generator (such as "lazy evaluation"), but here the xrange-iterable is endless, meaning that there may be infinite iterations on this xrange.
Because of Xrange's "lazy curiosity" feature, range () is usually faster than xrange () if you only need to iterate once (for example, in a For loop). However, it is not recommended to use range () in multiple iterations, because a range () will regenerate a list in memory each time.
In Python 3, range () is implemented in the same way as the xrange () function, so there is no dedicated xrange () (using xrange () in Python 3 will trigger Nameerror).
Import Timeit
n = 10000
def test_range (n):
return for I in range (n):
Pass
def test_xrange (n):
For I in Xrange (n):
Pass
Python 2
print ' Python ', python_version ()
print ' ntiming range () '
%timeit Test_range (N)
print ' nntiming xrange () '
%timeit Test_xrange (N)
Python 2.7.6
Timing Range ()
Loops, Best of 3:433μs per loop
Timing Xrange ()
Loops, Best of 3:350μs per loop
Python 3
Print (' Python ', Python_version ())
Print (' ntiming range () ')
%timeit Test_range (N)
Python 3.4.1
Timing Range ()
Loops, Best of 3:520μs per loop
Print (Xrange (10))
---------------------------------------------------------------------------
Nameerror Traceback (most recent)
In ()
----> 1 Print (xrange (10))
Nameerror:name ' xrange ' is not defined
The __contains__ method in the Range object in Python 3
Another noteworthy is that in Python 3.x, range has a new __contains__ method. The __contains__ method can effectively speed up the "find" speed of integers and Booleans in Python 3.x.
x = 10000000
def val_in_range (X, Val):
Return Val in range (x)
def val_in_xrange (X, Val):
Return Val in xrange (x)
Print (' Python ', Python_version ())
ASSERT (Val_in_range (x, X/2) = = True)
ASSERT (Val_in_range (x, X//2) = = True)
%timeit val_in_range (x, X/2)
%timeit val_in_range (x, X//2)
Python 3.4.1
1 loops, Best of 3:742 ms Per loop
1000000 loops, Best of 3:1.19μs per loop
Depending on the result of the above Timeit, finding an integer is about 60,000 times times faster than finding a floating-point number. However, because the range or xrange in Python 2.x does not have a __contains__ method, the lookup speed of integers and floating-point numbers in Python 2 differs little.
print ' Python ', python_version ()
ASSERT (Val_in_xrange (x, x/2.0) = = True)
ASSERT (Val_in_xrange (x, X/2) = = True)
ASSERT (Val_in_range (x, X/2) = = True)
ASSERT (Val_in_range (x, X//2) = = True)
%timeit val_in_xrange (x, x/2.0)
%timeit val_in_xrange (x, X/2)
%timeit val_in_range (x, x/2.0)
%timeit val_in_range (x, X/2)
Python 2.7.7
1 loops, Best of 3:285 ms Per loop
1 loops, Best of 3:179 ms Per loop
1 loops, Best of 3:658 ms Per loop
1 loops, Best of 3:556 ms Per loop
The following code proves that there is no __contain__ method in Python 2.x:
Print (' Python ', Python_version ())
Range.contains
Python 3.4.1
<slot Wrapper 'contains' of ' range ' objects
Print (' Python ', Python_version ())
Range.contains
Python 2.7.7
---------------------------------------------------------------------------
Attributeerror Traceback (most recent)
in ()
1 print ' Python ', python_version ()
----> 2 range. contains
Attributeerror: ' Builtin_function_or_method ' object has no attribute 'contains'
Print (' Python ', Python_version ())
Xrange. contains
Python 2.7.7
Attributeerror Traceback (most recent)
In ()
1 print ' Python ', python_version ()
----> 2 xrange. contains
Attributeerror:type object ' xrange ' has no attribute 'contains‘
A note about the speed difference between xrange () and range () in Python 3 in Python 2:
Readers have pointed out that the range () in Python 3 differs from the execution speed of xrange () in Python 2. Because the two are implemented the same way, the theoretical execution speed should be the same. The speed difference here is only because the overall speed of Python 3 is slower than Python 2.
Def test_while ():
i = 0
While I < 20000:
i + = 1
Return
Print (' Python ', Python_version ())
%timeit Test_while ()
Python 3.4.1
%timeit Test_while ()
Loops, Best of 3:2.68 ms Per loop
print ' Python ', python_version ()
%timeit Test_while ()
Python 2.7.6
Loops, Best of 3:1.72 ms Per loop
Triggering an exception
[Back to catalogue]
Python 2 supports both the old and new exception-triggering syntax, while Python 3 accepts only the parenthesized syntax (which would otherwise trigger SyntaxError):
Python 2
print ' Python ', python_version ()
Python 2.7.6
Raise IOError, "File Error"
---------------------------------------------------------------------------
IOError Traceback (most recent)
in ()
----> 1 raise IOError, "File Error"
Ioerror:file Error
Raise IOError ("File Error")
---------------------------------------------------------------------------
IOError Traceback (most recent)
In ()
----> 1 Raise IOError ("File Error")
Ioerror:file Error
Python 3
Print (' Python ', Python_version ())
Python 3.4.1
Raise IOError, "File Error"
File " ", line 1
Raise IOError, "File Error"
^
Syntaxerror:invalid syntax
The proper-raise an exception in Python 3:
Print (' Python ', Python_version ())
Raise IOError ("File Error")
Python 3.4.1
OSError Traceback (most recent)
In ()
1 print (' Python ', Python_version ())
----> 2 raise IOError ("File Error")
Oserror:file Error
Exception handling
[Back to catalogue]
The exception handling in Python 3 also changed a little. The "as" keyword must be used in Python 3.
Python 2
print ' Python ', python_version ()
Try
Let_us_cause_a_nameerror
Except Nameerror, err:
Print err, '--and our error message '
Python 2.7.6
Name ' Let_us_cause_a_nameerror ' is not defined--and our error message
Python 3
Print (' Python ', Python_version ())
Try
Let_us_cause_a_nameerror
Except Nameerror as err:
Print (Err, '--and our error message ')
Python 3.4.1
Name ' Let_us_cause_a_nameerror ' is not defined--and our error message
Next () function and the. Next () method
[Back to catalogue]
Because the next (. Next ()) function (method) is often used, it is also mentioned that another syntax change (implementation has also been changed): In Python 2.7.5, both the function form and the method form are available, whereas in Python 3, you can use only next () function (attempting to invoke the. Next () method will trigger Attributeerror).
Python 2
print ' Python ', python_version ()
My_generator = (letter-in ' ABCDEFG ')
Next (My_generator)
My_generator.next ()
Python 2.7.6
' B '
Python 3
Print (' Python ', Python_version ())
My_generator = (letter-in ' ABCDEFG ')
Next (My_generator)
Python 3.4.1
A
My_generator.next ()
---------------------------------------------------------------------------
Attributeerror Traceback (most recent)
in ()
----> 1 my_generator.next ()
Attributeerror: ' Generator ' object has no attribute ' next '
For loop variables and global namespace leaks
[Back to catalogue]
The good news: in Python 3.x, the variables in the for loop are no longer leaking into the global namespace!
This is a change made in Python 3.x and is described in the "What's New in Python 3.0" as follows:
"List deduction no longer supports [... for var in item1, Item2, ...] This syntax, using the [... for Var in (item1, item2, ...)] Replace. Also note that list derivation has different semantics: now the list derivation is closer to the syntax sugar such as the generator expression in the list () constructor, especially note that the loop control variable is no longer leaking into the space around the loop. ”
Python 2
print ' Python ', python_version ()
i = 1
print ' before:i = ', I
print ' comprehension: ', [i-I in range (5)]
print ' after:i = ', I
Python 2.7.6
BEFORE:I = 1
Comprehension: [0, 1, 2, 3, 4]
AFTER:I = 4
Python 3
Print (' Python ', Python_version ())
i = 1
Print (' before:i = ', i)
Print (' Comprehension: ', [i-I in range (5)])
Print (' after:i = ', i)
Python 3.4.1
BEFORE:I = 1
Comprehension: [0, 1, 2, 3, 4]
AFTER:I = 1
Compare unordered types
[Back to catalogue]
Another good change in Python 3 is that if we try to compare unordered types, a typeerror will be triggered.
Python 2
print ' Python ', python_version ()
Print "[1, 2] > ' foo ' =", [1, 2] > ' foo '
Print "(1, 2) > ' foo ' =", (1, 2) > ' foo '
Print "[1, 2] > (1, 2) =", [1, 2] > (1, 2)
Python 2.7.6
[1, 2] > ' foo ' = False
(1, 2) > ' foo ' = True
[1, 2] > (1, 2) = False
Python 3
Print (' Python ', Python_version ())
Print ("[1, 2] > ' foo ' =", [1, 2] > ' foo ')
Print ("(1, 2) > ' foo ' =", (1, 2) > ' foo ')
Print ("[1, 2] > (1, 2) =", [1, 2] > (1, 2))
Python 3.4.1
---------------------------------------------------------------------------
TypeError Traceback (most recent)
In ()
1 print (' Python ', Python_version ())
----> 2 Print ("[1, 2] > ' foo ' =", [1, 2] > ' foo ')
3 Print ("(1, 2) > ' foo ' =", (1, 2) > ' foo ')
4 Print ("[1, 2] > (1, 2) =", [1, 2] > (1, 2))
Typeerror:unorderable types:list () > str ()
Parsing the user's input via input ()
[Back to catalogue]
Fortunately, Python 3 improves the input () function so that the function will always store the user's input as a str object. In Python 2, in order to avoid some risky behavior of reading non-string types, you have to use Raw_input () instead of input ().
Python 2
Python 2.7.6
[GCC 4.0.1 (Apple Inc. build 5493)] on Darwin
Type "Help", "copyright", "credits" or "license" for more information.
My_input = input (' Enter a number: ')
Enter a number:123
Type (my_input)
<type ' int ' >
My_input = Raw_input (' Enter a number: ')
Enter a number:123
Type (my_input)
<type ' str ' >
Python 3
Python 3.4.1
[GCC 4.2.1 (Apple Inc. build 5577)] on Darwin
Type "Help", "copyright", "credits" or "license" for more information.
My_input = input (' Enter a number: ')
Enter a number:123
Type (my_input)
<class ' str ' >
Returns an iterative object instead of a list
[Back to catalogue]
As you can see in the Xrange section, some functions and methods return an iterative object in Python, rather than returning a list in Python 2.
Because these objects are usually traversed only once, this approach saves a lot of memory. However, if you iterate over these objects multiple times through the generator, the efficiency is not high.
At this point we do need a list object, which can be easily converted to a list by the list () function.
Python 2
print ' Python ', python_version ()
Print Range (3)
Print type (range (3))
Python 2.7.6
[0, 1, 2]
<type ' list ' >
Python 3
Print (' Python ', Python_version ())
Print (range (3))
Print (Type (range (3)))
Print (List (range (3)))
Python 3.4.1
Range (0, 3)
<class ' Range ' >
[0, 1, 2]
The following lists the other common functions and methods in Python 3 that no longer return a list:
Zip ()
Map ()
Filter ()
The. Key () Method of the dictionary
The. Value () Method of the dictionary
The. Item () Method of the dictionary
Summary of important differences between Python 2.7.x and 3.x versions