Python2.7 and python3.4 are different, but python2.7python3.4
Many beginners of Python want to know which version of Python they should start learning. My answer to this question is "you learn the version of your favorite tutorial and check the differences between them. "
But if you start a new project and have the right to choose? I would like to say that there is no right or wrong at present, as long as the library Python 2.7.x and Python 3.x are supported by both parties. Even so, when writing any of them or you plan to port your project, it is worth looking at the differences between the two popular Python versions, to avoid common traps,
Chapter
- Use
__future__Module
printFunction
- Integer division
- Unicode
- Xrange
- Raising exceptions
- Handling exceptions
next()Functions and.next()Method
- For Loop Variable and global namespace Leakage
- Comparison of non-sorting types
- Pass
input()Parse user input
- Returns the iteratable object instead of the list.
- More articles about Python 2 and Python 3
FutureModule
Python 3.x introduces some incompatible keywords and features of Python 2.__future__Module import. If you plan to allow your code to support Python 3.x, we recommend that you use__future__Module import. For example, if I want to demonstrate the division in Python 3.x in Python 2, we can import
from __future__ import division
More__future__The features that can be imported by the module are listed in the following table:
| Feature |
Optional in |
Mandatory in |
Effect |
| Nested_scopes |
2.1.0b1 |
2.2 |
PEP 255: Simple Generators |
| Division |
2.2.0a2 |
3.0 |
PEP 328: Imports: Multi-Line and Absolute/Relative |
| With_statement |
2.5.0a1 |
2.6 |
PEP 3105: Make print a function |
| Unicode_literals |
2.6.0a2 |
3.0 |
<A rel = "nofollow" href = "http://legacy.python.org/dev/peps/pep-3112/" = "" target = "_ blank" style = "color: rgb (128, 0,128); text-decoration: none; outline-style: none; "> PEP 3112: Bytes literals in Python 3000 |
(Source: https://docs.python.org/2/library/future.html)
from platform import python_version
PrintFunction
[Jump to Chapter Preview]
Very trivial, andprintSyntax changes may be the most widely known, but it is worth mentioning that: Python 2printThe statement has beenprint()The function is replaced, which means we have to wrap the object we want to print in parentheses.
Python 2 does not have any additional parentheses. But for comparison, if we do not use parentheses to call Python 2printFunction, Python 3 will throw a syntax exception (SyntaxError).
Python 2
print 'Python', python_version()print 'Hello, World!'print('Hello, World!') print "text", ; print 'print more text on the same line'
Python 2.7.6Hello, 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.1Hello, World!some text, print more text on the same line
print 'Hello, World!'
File "<ipython-input-3-139a7c5835bd>", line 1 print 'Hello, World!' ^SyntaxError: invalid syntax
Note:
Use Python 2Printing "Hello, World"However, if you have multiple objects in parentheses, we will create a tuples becauseprintIn Python 2, it is a declaration rather than a function call.
print 'Python', python_version()print('a', 'b') print 'a', 'b'
Python 2.7.7('a', 'b')a bDivision
[Jump to Chapter Preview]
This change is especially dangerous if you are porting code. Or you can execute Python 3 code on Python 2. Because this division change is manifested in the fact that it will be ignored (that is, it will not throw a syntax exception ).
Therefore, I prefer to usefloat(3)/2Or3/2.0Instead of saving my Python 3 script in Python 23/2(And the same is true. I suggest using it in your Python 2 script .)from __future__ import division)
Python 2
print 'Python', python_version()print '3 / 2 =', 3 / 2print '3 // 2 =', 3 // 2print '3 / 2.0 =', 3 / 2.0print '3 // 2.0 =', 3 // 2.0
Python 2.7.63 / 2 = 13 // 2 = 13 / 2.0 = 1.53 // 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.13 / 2 = 1.53 // 2 = 13 / 2.0 = 1.53 // 2.0 = 1.0
Unicode
[Jump to Chapter Preview]
Python 2 hasASCII str()Type,unicode()Is independent, not a byte type.
Now, in Python 3, we finally haveUnicode (utf-8)String and a byte class:byteAndbytearrays.
Python 2
print 'Python', python_version()
Python 2.7.6
print type(unicode('this is like a python3 str type'))<type 'unicode'>
print type(b'byte type does not exist')<type 'str'>
print 'they are really' + b' the same'they are really the same
print type(bytearray(b'bytearray oddly does exist though'))<type 'bytearray'>
Python 3
print('Python', python_version()) print('strings are now utf-8 u03BCnicou0394é!') Python 3.4.1 strings are now utf-8 μnicoΔé!
print('Python', python_version(), end="")print(' has', 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 call last)<ipython-input-13-d3e8942ccf81> in <module>() ----> 1 'note that we cannot add a string' + b'bytes for data' TypeError: Can't convert 'bytes' object to str implicitly
Xrange
[Jump to Chapter Preview]
In Python 2xrange()The usage of creating iterative objects is very popular. For example, for loop or list/set/dictionary derivation.
This is like a generator (for example. "Evaluate inertia "). But thisxrange-iterableIs infinite, meaning you can traverse infinitely.
Because of its inertia, if you do not just traverse it once,xrange()Function Ratiorange()Faster (for example, for loop ). Even so, we do not recommend that you repeat the iteration multiple times because the generator starts from the beginning each time.
In Python 3,range()Yesxrange()So that a dedicatedxrange()Functions no longer exist (in Python 3xrange()Will throw a naming exception ).
import timeitn = 10000def test_range(n): return for i in range(n): passdef 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.6timing range()1000 loops, best of 3: 433 µs per looptiming xrange()1000 loops, best of 3: 350 µs per loop
Python 3
print('Python', python_version())print('ntiming range()')%timeit test_range(n)Python 3.4.1timing range()1000 loops, best of 3: 520 µs per loop
print(xrange(10)) --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-5-5d8f9b79ea70> in <module>() ----> 1 print(xrange(10))NameError: name 'xrange' is not defined
In Python 3rangeObject__contains__Method
Another thing worth mentioning is in Python 3.rangeThere is a new__contains__Method (thanks to Yuchen Ying for pointing out this ),__contains__Method can be accelerated"Search"Significant integers and Boolean types in Python 3.x.
x = 10000000def 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.11 loops, best of 3: 742 ms per loop1000000 loops, best of 3: 1.19 µs per loop
Based on the abovetimeitWhen it makes an integer type instead of a floating point type, you can see that the search speed is 60000 times faster. However, because Python 2.x'srangeOrxrangeNone__contains__Method. The query speed of this integer or floating point type does not differ much.
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.71 loops, best of 3: 285 ms per loop1 loops, best of 3: 179 ms per loop1 loops, best of 3: 658 ms per loop1 loops, best of 3: 556 ms per loop
Next__contain__The method is not added to 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 call last)<ipython-input-7-05327350dafb> in <module>() 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 call last)<ipython-input-8-7d1a71bfee8e> in <module>() 1 print 'Python', python_version() ----> 2 xrange.__contains__ AttributeError: type object 'xrange' has no attribute '__contains__'
** Note the speed difference between Python 2 and Python 3 ***
Some ape class points out that Python 3'srange()And Python 2xrange()The speed is different. Because they are implemented in the same way, they expect the same speed. However, the fact is that Python 3 tends to be 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.1100 loops, best of 3: 2.68 ms per loop
print 'Python', python_version()%timeit test_while()Python 2.7.61000 loops, best of 3: 1.72 ms per loop
Raising exceptions
[Jump to Chapter Preview]
Python 2 accepts the New and Old syntax tags. in Python 3, if I do not use parentheses to enclose exception parameters, it will block (and in turn throw a syntax exception ).
Python 2
print 'Python', python_version()Python 2.7.6
raise IOError, "file error"---------------------------------------------------------------------------IOError Traceback (most recent call last) <ipython-input-8-25f049caebb0> in <module>() ----> 1 raise IOError, "file error" IOError: file error
raise IOError("file error")---------------------------------------------------------------------------IOError Traceback (most recent call last)<ipython-input-9-6f1c43f525b2> in <module>() ----> 1 raise IOError("file error") IOError: file error
Python 3
print('Python', python_version()) Python 3.4.1
raise IOError, "file error"
File "<ipython-input-10-25f049caebb0>", line 1 raise IOError, "file error" ^SyntaxError: invalid syntaxThe proper way to raise an exception in Python 3:
print('Python', python_version()) raise IOError("file error") Python 3.4.1 --------------------------------------------------------------------------- OSError Traceback (most recent call last) <ipython-input-11-c350544d15da> in <module>() 1 print('Python', python_version()) ----> 2 raise IOError("file error")OSError: file errorHandling exceptions
Processing exceptions in Python 3 are also slightly changed. In Python 3, we useasAs a keyword.
Python 2
print 'Python', python_version()try: let_us_cause_a_NameErrorexcept NameError, err: print err, '--> our error message'Python 2.7.6name 'let_us_cause_a_NameError' is not defined --> our error message
Python 3
print('Python', python_version())try: let_us_cause_a_NameErrorexcept NameError as err: print(err, '--> our error message')Python 3.4.1name 'let_us_cause_a_NameError' is not defined --> our error messageNext () function and. next () method
Becausenext() (.next())It is such a common function (method). Here there is another syntax change (or the implementation has changed). It is worth mentioning that: you can use functions and methods in Python 2.7.5,next()Functions are retained in Python 3 (called.next()Throw a property exception ).
Python 2
print 'Python', python_version()my_generator = (letter for letter in 'abcdefg')next(my_generator) my_generator.next()
Python 2.7.6'b'
Python 3
print('Python', python_version()) my_generator = (letter for letter in 'abcdefg') next(my_generator)
Python 3.4.1'a'
my_generator.next()
---------------------------------------------------------------------------AttributeError Traceback (most recent call last) <ipython-input-14-125f388bb61b> in <module>() ----> 1 my_generator.next() AttributeError: 'generator' object has no attribute 'next'
For Loop Variable and global namespace Leakage
Good news: in Python 3.x, for loop variables will no longer cause namespace leakage.
A change was made In Python 3.x, which is described below In What's New In Python 3.0:
"List derivation does not support syntax such as [... for var in item1, item2. Use [... for var in (item1, item2,...)] instead. Note that list derivation has different semantics: They disable the syntax sugar of the generator expression in the 'list () 'constructor, in addition, cyclic control variables are not leaked into the surrounding scope."
Python 2
print 'Python', python_version()i = 1print 'before: i =', iprint 'comprehension: ', [i for i in range(5)]print 'after: i =', iPython 2.7.6before: i = 1comprehension: [0, 1, 2, 3, 4]after: i = 4
Python 3
print('Python', python_version())i = 1print('before: i =', i)print('comprehension:', [i for i in range(5)])print('after: i =', i)Python 3.4.1before: i = 1comprehension: [0, 1, 2, 3, 4]after: i = 1Comparison of non-sorting types
Another change in Python 3 is that a type error is thrown when the unsortable type is compared.
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 call last) <ipython-input-16-a9031729f4a0> in <module>() 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()Pass
input()Parse user input
Fortunately, Python 3 has solved the problem of storing user input asstrObject. We have to useraw_input().
Python 2
Python 2.7.6 [GCC 4.0.1 (Apple Inc. build 5493)] on darwinType "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 darwinType "help", "copyright", "credits" or "license" for more information.>>> my_input = input('enter a number: ')enter a number: 123>>> type(my_input)<class 'str'>Returns the iteratable object instead of the list.
If you see this in the xrange Section, some methods and functions in Python 3 now return iterative objects-instead of the list in Python 2
Because we usually only traverse once, I think this change makes sense to save memory. Even so, it is also possible, as opposed to the generator-if you need to traverse multiple times. It is not so efficient.
In those cases, what we really need is a list object.list()The function simply converts an iteration object into a list.
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]
Some frequently used functions and methods in Python 3 that do not return a list:
-
Zip ()
-
Map ()
-
Filter ()
-
Dictionary's. keys () method
-
Dictionary's. values () method
-
Dictionary's. items () method
More articles about Python 2 and Python 3
Below are some good articles about Python 2 and Python 3 I suggest.
Port to Python 3
-
Shocould I use Python 2 or Python 3 for my development activity?
-
What's New In Python 3.0?
-
Porting to Python 3
-
Porting Python 2 Code to Python 3
-
How keep Python 3 moving forward
Advocates and opponents of Python 3
-
10 awesome features of Python that you can't use because you refuse to upgrade to Python 3
-
Everything you did not want to know about Unicode in Python 3
-
Python 3 is killing Python
-
Python 3 can revive Python
-
Python 3 is fine