稀有猿诉

十年磨一剑,历炼出锋芒,说话千百句,不如码二行。

Python 2升级到Python 3的指导建议

“Life is short, we must upgrade to Python 3”

Python是一个非常好用的工具语言,哪怕主业中用不到它,到处可见到一些非常实用的小的工具都是用Python来写的,即使再小的工具,也要做到小而美,这是工匠精神的体现。在社区里面Python 2已经停止开发新功能了,仅维护并修复一些bug,未来也将会停止维护,有些平台已经默认用python3了。除非有些无法替换的依赖必须强制使用Python 2以外,建议要升级到Python 3。本篇记录一些朕在升级到Python 3时遇到的一些问题,也即升级的时候的一些指导提示。

Python 2与Python 3的区别

两个版本并不兼容

就像刚接触Python时,竟然发现它有两个版本,而且它们还不兼容,具体原因可能是因为时代的发展,编程语言也在不断的进步,而Python语言并不年轻,所以可能会导致新的编程语言设计思想在老的版本上面不好去兼容,很多软件都会有这样的问题,当有跨度比较大的升级时,相当于重新设计了,基本上是取代而非升级,因为老版本的设计架构等原因,是无法兼容的。

姑且不管啥原因吧,我们要明白一个事实就是Python 2与Python 3是不兼容的,意思就是,如果按照Python 2写的一段代码,用Python 3的解释器去运行,会报错,无法运行,反之亦然。

两个版本的主要区别

关于两方面的区别,可以看一看这篇文章,写的比较详细,这里就不重复了,只是罗列一些最常用的,也是最显著的一些需要注意的地方:

print

在Python 2里面啊,print是一个语言关键字,就像if when一样,它是一个独立的语句,想输出啥东西时,都是直接在print后面写就行了:

1
2
print 1, 2, 3
print 'Security code is ', a, b, c

而Python 3里面,print是一个内置函数,必须带有()才算函数调用,这里不纠结语句与函数的区别,只需要记得,现在要在print后面加上括号就可以了,下面的代码与上面效果等同:

1
2
print(1, 2, 3)
print('Security code is ', a, b, c)

字符串编码

这个可能是最复杂的和令人困惑的,根本的原因在于Python 2中的字符串与编码问题很绕,而Python 3中就清晰多了。

在Python 2里面字符串与字符的类型是不一样的,它与上一代的编程语言(C)有点类似,ASCII的与Unicode是不同的类型:

1
2
a = 'abcd'
b = u'早上好'

这里面a是一个string,而b是一个unicode str,如果 不加u,直接写unicode字符会报错的,可以通过unicode函数转化为unicode str,以及通过str函数转化为ASCII字符串。

而在Python 3中不再这么绕了,它就一种字符串类型str,支持unicode,所以你可以直接写了:

1
2
a = 'abcd'
b = '下午好'

可以简单的来理解,把Python 2里的字串想像为C语言,而Python 3的字串相像为Java就可以了。

注意: 关于字串与编码比较复杂,后面会单独的文章来介绍。

重要模块的迁移

大部分的模块是没有变动的,也即import时没有变化,但是有一些有比较大的变化,原因也是相关的代码在设计上有了重大变更,最明显的就是HTTP相关,原来比较乱有httplib, cookie, urllib2等一坨,现在都集中在了urllib里面。详细的可参见上面推荐的文章。

遍历字典和列表

字典遍历有变化 :

1
2
3
# data is a dictionary
for k, v in data.items(): # not iteritems()
   print('{} -> {}.format(k, v))

遍历平行列表时有变化 :

1
2
3
# sections, departments are lists
for s, d in zip(sections, departments):
   print(s, d)

而在Python 2里面必须 这样写:

1
2
3
import itertools
for s, d in itertools.zip(sections, departments):
   print s, d

解释器的选择

上面是代码层面的区别和要注意的点,代码写好了要执行啊,执行的时候也需要注意,用错了解释器,还是跑不通的。

目前大部分的平台上面(Ubuntu和Mac OSX)的系统默认解释器还是2.7.x版本的:

1
2
3
4
[-> ~] which python
/usr/bin/python
[-> ~] ll /usr/bin/python
/usr/bin/python -> python2.7

但是呢,不建议强行把系统的默认解释器换成Python 3,这可能会导致系统出问题,我们直接让我们的脚本用Python 3来运行就可以了,在shebang中改:

1
#!/usr/bin/env python3

或者如果是使用PyCharm的话,在项目配置上直接选择Python 3的解释器就好了。

用pip3安装依赖

同时,安装需要的依赖时也使用pip3而非pip:

1
2
3
sudo apt-get install python3-pip
pip3 install --upgrade pip
pip3 install pandas

思维的转变

这里仅是罗列出一些非常显著 的变化 ,实际上远不止这些,大版本的跳跃哪能就这么一点变化呢,还有想当多的细节问题可能会在日常使用中遇到。

这里想说的是如果遇到问题,比如在Python 3中报错了,或者某个问题不知道怎么搞,在搜索答案时,或者寻求帮助时记得直接搜索『Python 3』,这会比较明确的把范围限定 在Python 3里面。

参考资料

Comments