The difference between python2 and 3, how to easily switch between 2 and 3

The following are listed in the rookie tutorial. These scattered changes require attention.

The following things may not be used in normal programs at all, or a little attention is enough. But the main difference between 2 and 3 is the mastery of coding.

Encoding is ubiquitous in all programs. If it is not handled properly, it will either be garbled, or an error will be reported when encoding and decoding. Once you have mastered the difference in coding, you can master 90% of the difference between 2 and 3, and only by mastering this can you switch versions freely.

Regarding encoding, there are three places, the first line of the program, the built-in encoding method of python, and the encoding of the console of the software cmd/pycahrmide. It is these three places that need to be clarified.

The default encoding of 2 is sacii, and 3 is utf8. You can use sys.getdefualencoding() to confirm why there is a program setting sys.setdefualencoding(‘utf8/gbk’). This is to modify the default encoding. You can also choose not to, but you need to explicitly write out the decoding/encoding method every time you decode.

Then you need to know that the string of 2 is the bytes of 3, and the unicode of 2 is the string of 3.

The primary reason for not being able to switch freely is coding. The following differences do not appear in every program, but coding is silently affecting every program.

Difference between Python2.x and 3.x

Version 3.0 of Python, often referred to as Python 3000, or Py3k for short. This is a major upgrade over earlier versions of Python.

In order not to bring too much burden, Python 3.0 did not consider backward compatibility when designing.

Many programs designed for earlier versions of Python will not run properly on Python 3.0.

In order to take care of existing programs, Python 2.6, as a transitional version, basically uses the syntax and libraries of Python 2.x, and at the same time considers the migration to Python 3.0, allowing the use of some syntax and functions of Python 3.0.

It is recommended to use the syntax of Python 3.0 for new Python programs.

Unless the execution environment cannot install Python 3.0 or the program itself uses a third-party library that does not support Python 3.0. Currently, third-party libraries that do not support Python 3.0 include Twisted, py2exe, PIL, etc.

Most third-party libraries are working hard to be compatible with Python 3.0 version. Even if Python 3.0 cannot be used immediately, it is recommended to write a program compatible with Python 3.0, and then use Python 2.6, Python 2.7 to execute.

The changes in Python 3.0 are mainly in the following aspects:

print function

The print statement is gone, replaced by the print() function. Python 2.6 and Python 2.7 partially support this form of print syntax. In Python 2.6 and Python 2.7, the following three forms are equivalent:

print "fish"
print ("fish") #Note that there is a space after print print("fish") #print() cannot have any other parameters

However, Python 2.6 actually supports the new print() syntax:

from __future__ import print_function
print("fish", "panda", sep=', ')

Unicode

Python 2 has the ASCII str() type, unicode() alone, not the byte type.

Now, in Python 3, we finally have Unicode (utf-8) strings, and a byte class: byte and bytearrays.

Since Python3.X source code files use utf-8 encoding by default, this makes the following code legal:

>>> 中国 = 'china' >>>print(中国) china

Python 2.x

>>> str = "I love Beijing Tiananmen" >>> str '\xe6\x88\x91\xe7\x88\xb1\xe5\x8c\x97\ \xe4\xba\xac\xe5\xa4\xa9\xe5\xae\x89\xe9\x97\xa8' >>> str = u"I love Beijing Tiananmen\ " >>> str u'\\我\\爱\\北\\京\\天\\安\\门'

Python 3.x

>>> str = "I love Beijing Tiananmen" >>> str 'I love Beijing Tiananmen'

Division operation

The division in Python is very high-end compared with other languages, and has a very complicated set of rules. Division in Python has two operators, / and //

First talk/division:

In python 2.x, /division is similar to most languages we are familiar with, such as Java and C. The result of integer division is an integer, and the decimal part is completely ignored. Floating point division will keep the decimal point to get a The result of a floating point number.

In python 3.x / division does not do this anymore, and for division between integers, the result will also be a floating point number.

Python 2.x:

>>> 1 / 2 0 >>> 1.0 / 2.0 0.5

Python 3.x:

>>> 1/2 0.5

As for //division, this kind of division is called floor division, which will automatically perform a floor operation on the result of division, which is consistent in python 2.x and python 3.x.

python 2.x:

>>> -1 // 2 -1

python 3.x:

>>> -1 // 2 -1

Note that the decimal part is not discarded, but the floor operation is performed. If you want to intercept the decimal part, you need to use the trunc function of the math module

python 3.x:

>>> import math
>>> math.trunc(1 / 2) 0 >>> math.trunc(-1 / 2) 0

Exception

Exception handling has also changed slightly in Python 3, where we now use as as a keyword.

Syntax for catching exceptions changed from except exc, var to except exc as var.

Use the syntax except (exc1, exc2) as var to catch multiple types of exceptions at the same time. Python 2.6 already supports both syntaxes.

  • 1. In the 2.x era, all types of objects can be thrown directly. In the 3.x era, only objects that inherit from BaseException can be thrown.
  • 2. The 2.x raise statement uses a comma to separate the thrown object type from the parameters. 3.x cancels this weird way of writing, and just calls the constructor to throw the object.

In the 2.x era, in addition to expressing program errors in the code, exceptions often do some things that ordinary control structures should do. In 3.x, it can be seen that the designer makes exceptions more specific, and only when errors occur The situation can be handled with an exception catch statement.

xrange

The use of xrange() to create iterator objects is very popular in Python 2. For example: for loop or list/set/dictionary comprehension.

This behaves very much like a generator (eg. “lazy evaluation”). But this xrange-iterable is infinite, which means you can traverse infinitely.

Due to its lazy evaluation, the xrange() function is faster than range() if you have to iterate over it only once (like a for loop). However, rather than iterating once, it is not recommended that you iterate multiple times, because the generator starts from scratch each time.

In Python 3, range() is implemented like xrange() so that a dedicated xrange() function no longer exists (xrange() throws the named exception in Python 3).

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 '\\
timing range()' %timeit test_range(n) print '\\
\\
timing xrange()' %timeit test_xrange(n) Python 2.7.6 timing range() 1000 loops, best of 3: 433 μs per loop timing xrange() 1000 loops, best of 3: 350 μs per loop

Python 3

print('Python', python_version()) print('\\
timing range()') %timeit test_range(n) Python 3.4.1 timing 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

Octal literal representation

Octal numbers must be written as 0o777, the original form of 0777 cannot be used; binary must be written as 0b111.

Added a bin() function for converting an integer to a binary string. Python 2.6 already supports both syntaxes.

In Python 3.x, there is only one way to represent an octal literal, which is 0o1000.

python 2.x

>>> 0o1000
512 >>> 01000 512

python 3.x

>>> 01000
  File "<stdin>", line 1 01000 ^ SyntaxError: invalid token >>> 0o1000 512

Not equal operator

There are two ways of writing not equal in Python 2.x != and <>

In Python 3.x, <> is removed, and only != is written. Fortunately, I have never used <>

Removed the repr expression“

The backtick “ in Python 2.x is equivalent to the role of the repr function

In Python 3.x, the “ is removed, and only the repr function is allowed. Is the purpose of doing this to make the code look clearer? However, I feel that there are very few opportunities to use repr. Generally, it is only used when debugging. Most of the time, the str function is still used to describe objects with strings.

def sendMail(from_: str, to: str, title: str, body: str) -> bool: pass

Multiple modules were renamed (according to PEP8)

old name new name
_winreg winreg
ConfigParser configparser
copy_reg copyreg
Queue queue
SocketServer socketserver
repr reprlib

The StringIO module is now merged into the new io module. New, md5, gopherlib and other modules are removed. Python 2.6 already supports the new io module.

httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib are merged into http package.

The exec statement is canceled, leaving only the exec() function. Python 2.6 already supports the exec() function.

5. Data type

1) Py3.X removes the long type, now there is only one integer type – int, but it behaves like the 2.X version of long

2) The bytes type is added, corresponding to the octet string of version 2.X. The method of defining a bytes literal is as follows:

>>> b = b'china' >>> type(b) <type 'bytes'>

str object and bytes object can use .encode() (str -> bytes) or .decode() (bytes -> str) method to convert each other.

>>> s = b.decode() >>> s 'china' >>> b1 = s.encode() >>> b1 b'china'

3) The .keys(), .items, and .values() methods of dict return iterators, while the previous functions such as iterkeys() are discarded. Also removed is dict.has_key(), replace it with in.