This article mainly introduces several examples of code that is compatible with Python and Python 3.x, in Python2.7.x, because some Python 3 code writing features are used, it is possible to write compatibility code in some original differences. For more information, see
Write compatible Python and 3.x code
When we are in Python 2. x to Python 3. during the transition period of x, you may wonder if you can run Python 2 and 3 simultaneously without modifying any code. This seems to be a reasonable demand, but how can we start? Which Python 2 codes are vulnerable to errors when being executed by the 3.x interpreter?
Print vs print ()
If you want to be the same as me, you may say the print statement. this is a good start. First, we will briefly show you that print is in 2. x is a statement, while 3. x is a keyword or reserved word. In other words, because this change involves the syntax of the language, you cannot use it in the if statement. Python still does not have the # ifdef macro. Next we try to print out the parameters in the brackets:
>>> print('Hello World!')Hello World!
Cool, this can be run in both Python2 and Python3, and the running effect is the same. let's take a look at the following section:
>>> print(10, 20) # Python 2(10, 20)
In this case, you are not lucky enough to get the same result as before. in Python2, tuple is printed, and multiple parameters are passed to print () in Python3 () two values are printed:
>>> print(10, 20) # Python 310 20
If you think a lot, we can check whether print is a keyword. the keyword module contains a list of keywords. Print is not a keyword in 3.x. you can simply verify it:
>>> import keyword>>> 'print' in keyword.kwlistFalse
As a smart programmer, you may be. the expected result in the attempt in x is True. although there is nothing wrong with this, but to achieve the effect of Python3, you will still fail for other reasons.
>>> import keyword>>> if 'print' in keyword.kwlist:... from __future__ import print_function...File "", line 2SyntaxError: from __future__ imports must occur at the beginning of the file
One solution is to use a function with functions similar to print, one of which is sys. stdout. write (), and the other is distutils. log. warn (). For whatever reason, we decided to use the latter. The "hello world" example looks like this:
# Python 2.xprint 'Hello World!'# Python 3.xprint('Hello World!')
The following code can be used in both versions:
# Python 2.x & 3.x compatiblefrom distutils.log import warn as printfprintf('Hello World!')
Why don't we use sys. stdout. write (), because we need to add a NEWLINE character at the end of the string to be compatible with this behavior (the write method in python2.x will not wrap the line ):
# Python 2.x & 3.x compatibleimport syssys.stdout.write('Hello World!n')
Import your way to a solution
In general, there is no need to worry about the import, as long as the import is correct, but in the following code, we want to import the urlopen () function, in Python2, he exists in both urllib2 and urllib2 (we use the latter). in Python3, he is integrated into urllib. request, and your solution must be in the 2. x and 3. x works normally:
try: from urllib2 import urlopenexcept ImportError: from urllib.request import urlopen
For memory protection, you may be more interested in iterator (Python3) version zip (). in Python2, iterator version is itertools. izip (). This function is renamed in Python3 and replaced with zip (). If you use an iterative version, the import statement is straightforward:
try: from itertools import izip as zipexcept ImportError: pass
Another column is a StringIO class that is not very elegant. in Python2, the pure Python version is the StringIO module, which means that the access is through StringIO. stringIO also has a faster C language version, which is located in cStringIO. stringIO, but it depends on your Python installation version. you can prioritize cStringIO and then StringIO (if cStringIO is unavailable ). In Python3, Unicode is the default string type. However, if you perform any network-related operations, you may have to use ASCII/byte strings. Therefore, instead of StringIO, you want io. to achieve what you want, the import looks ugly:
try: from io import BytesIO as StringIOexcept ImportError: try: from cStringIO import StringIO except ImportError: from StringIO import StringIO
Putting it all together
If you are lucky, the above is all you need to prepare, and the rest of the code is simpler than the start setting. If you have imported distutils as follows. log. warn () [printf ()], url * urlopen (),*. stringIO and a standard import: xml. etree. elementTree (2.5 and updated), now you can write a very simple and short parser to show the headlines provided by the Google News service ), only eight lines of code are required:
g = urlopen('http://news.google.com/news?topic=h&output=rss')f = StringIO(g.read())g.close()tree = xml.etree.ElementTree.parse(f)f.close()for elmt in tree.getiterator(): if elmt.tag == 'title' and not elmt.text.startswith('Top Stories'): printf('- %s' % elmt.text)
This script is in step 2. x and 3. if you are running version 2.4 or older, you need to download ElementTree separately.
But sometimes it seems that these changes make a mess of your elegant Python code. after all, readability is the most important thing, if you want to ensure that the code is clean and runs in two versions of Python without any modification, you can take a look at the six package.
Six is a compatible library. its main task is to provide interfaces to hide complex details. you can find it here. Whether you are using a library like six or your own method, we hope this brief introduction will allow you to start thinking about writing code in 2. x and 3. x.