首页 > 编程 > Python > 正文

编写同时兼容Python2.x与Python3.x版本的代码的几个示例

2020-02-23 00:27:07
字体:
来源:转载
供稿:网友

编写兼容Python2.x与3.x代码

当我们正处于Python 2.x到Python 3.x的过渡期时,你可能想过是否可以在不修改任何代码的前提下能同时运行在Python 2和3中。这看起来还真是一个合理的诉求,但如何开始呢?哪些Python 2 代码在 3.x 解释器执行时容易出状况呢?
print vs print()

如果你想的和我一样,你或许会说print语句,这是个很好的着手点,先简单展示一下,print在2.x中是一条语句,而在3.x中它是一个关键字或者是保留字。换句话说,因为这个变化涉及到语言的语法,你不可以使用在if语句中,Python仍然没有#ifdef 宏。下面尝试把括号里面的参数打印出来:

>>> print('Hello World!')Hello World!

很酷,这个在Python2和Python3中都可以运行,而且运行的效果是一样的,再来看看下面这段:
 

>>> print(10, 20) # Python 2(10, 20)

此时,你并没有像前面那样幸运得到一样的结果,Python2中打印的是元组(tuple),而在Python3中传递多个参数到print()里面时打印的是两个值:
 

>>> print(10, 20) # Python 310 20

如果你思考得比较多的话,我们可以检查print是否是一个关键字,keyword模块包含一个关键字列表。print在3.x中不是关键字,可以简单验证一下:
 

>>> import keyword>>> 'print' in keyword.kwlistFalse

作为一名聪明的程序员,你可能在2.x中尝试的时候期待的结果是True,尽管这并没有错,但是为了达到Python3的效果,但你仍然会因为其他原因导致失败。
 

>>> 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

一种解决方案是使用一个函数,其功能类似于print,其中之一是sys.stdout.write(),另一个是distutils.log.warn()。不管出于什么原因,我们决定使用后者。“hello world”的例子看起来是这样的:
 

# Python 2.xprint 'Hello World!'# Python 3.xprint('Hello World!')

下面的代码就可以在两个版本中通用:
 

# Python 2.x & 3.x compatiblefrom distutils.log import warn as printfprintf('Hello World!')

为什么我们不用sys.stdout.write()呢,因为我们需要添加一个NEWLINE字符在字符串的结尾来兼容这种行为(python2.x中write方法不会换行):
 

# Python 2.x & 3.x compatibleimport syssys.stdout.write('Hello World!n')

Import your way to a solution

一般情况情况下,import时没什么烦恼,只要正确的导入就行,但在下面代码中,我们想导入urlopen()函数,在Python2中,他同时存在与urllib2和urllib2中(我们使用后者),在Python3中,他被集成到了urllib.request中,而你的方案是要既能在2.x和3.x中正常工作:

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表