许多python初学者都在为难到底是选择python2还是python3,我刚刚学python的时候也有这个疑问。大佬们各有个的说法,但学完基础之后,我觉得你选一个适合自己的就是最好的了,看哪个爽就学哪个。开源东西没有专门维护和标准,果然还是够但疼。
我觉得也没有什么好坏之分,简单了解了之后,你会发现他们支持的库已经基本差不太多了。这里就简单的说说两个版本的一些区别,以免后面东西学咋了就什么都忘了。
这应该是python中最有用的模块之一了,虽然python3中有一些python2不支持的关键字和特性,但他们都可以在python2的__future__
中找到。所以如果你打算在你的python2中体验python3语言的特性,就可以简单通过导入__future__模块。比如说我们想在python2中使用python3的整除算法,可以这样做
from __future__ import division
当然,__future__并不是专门为从python2跨越到python3准备的,它只是提供了向后兼容,也就是说python2.1中的__future__可以导入python2.2的特性,以此类推。
print在python2中还只是一个表达式,但在python3中已经成了一个函数调用了,所以括号必不可少。
python2里面这样写
print 'Python', python_version()
print 'Hello, World!'
print('Hello, World!')
print('Hello','World!')
print "text", ; print 'print more text on the same line'
它会给出这样的答案
Python 2.7.6
Hello, World!
Hello, World!
('Hello','World!')
text print more text on the same line
python3中这样写
print('Python', python_version())
print('Hello, World!')
print("some text,", end="")
print(' print more text on the same line')
会给出这样的答案
Python 3.4.1
Hello, World!
some text, print more text on the same line
当然,如果你不争气的在python3中写出了这样的代码
print 'Hello, World!'
那你就只能得到这样的答案
File "<ipython-input-3-139a7c5835bd>", line 1
print 'Hello, World!'
^
SyntaxError: invalid syntax
这个改变有点变态,因为如果当你把python2的代码移植到python3上的时候,虽然写法一样,但是操作结果却不一样。
比如在python2中
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 2.7.6
3 / 2 = 1
3 // 2 = 1
3 / 2.0 = 1.5
3 // 2.0 = 1.0
但是在python3中同样的代码
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.1
3 / 2 = 1.5
3 // 2 = 1
3 / 2.0 = 1.5
3 // 2.0 = 1.0
所以这个坑等着你跳,而且相信有很多人会跳
python2使用的是ASCII编码来表示字符串,与unicode()不同,而且没有byte类型。 python3默认是使用Unicode(UTF-8)来表示字符串,并且有byte和bytearrays两种类型(类)。
python2的如下代码
print type(unicode('this is like a python3 str type'))
print type(b'byte type does not exist')
print 'they are really' + b' the same'
print type(bytearray(b'bytearray oddly does exist though'))
将得到如下输出
<type 'unicode'>
<type 'str'>
they are really the same
<type 'bytearray'>
print('strings are now utf-8 \u03BCnico\u0394é!')
print(' has', type(b' bytes for storing data'))
print('and Python', python_version(), end="")
将得到下面输出
strings are now utf-8 μnicoΔé!
has <class 'bytes'>
also has <class 'bytearray'>
这里只是写法不一样,python2允许使用两种错误抛出的写法,python3中值允许一种,如下:
在python2中
raise IOError, "file error"
raise IOError("file error")
都可以可以得到输出
---------------------------------------------------------------------------
IOError Traceback (most recent call last)
<ipython-input-8-25f049caebb0> in <module>()
----> 1 raise IOError, "file error"
IOError: file error
在python3中只有
raise IOError("file error")
才能得到正确的输出
python2中的except表达式如下
try:
let_us_cause_a_NameError
except NameError, err:
print err, '--> our error message'
但在python3中必须使用as关键字,有些不习惯。
try:
let_us_cause_a_NameError
except NameError as err:
print(err, '--> our error message')
他们都能输出
name 'let_us_cause_a_NameError' is not defined --> our error message
这是一个很棒的改进,for-loop中的变量不再会泄漏到全局命名空间了!
比如在python2中
i = 1
print 'before: i =', i
print 'comprehension: ', [i for i in range(5)]
print 'after: i =', i
会得到这样的输出
before: i = 1
comprehension: [0, 1, 2, 3, 4]
after: i = 4
在python3中,就正常了
i = 1
print('before: i =', i)
print('comprehension:', [i for i in range(5)])
print('after: i =', i)
输出是这样的
before: i = 1
comprehension: [0, 1, 2, 3, 4]
after: i = 1
还有一个重要的改变是比较功能,不同类型比较的时候python3会抛出错误了。
python2代码如下
print "[1, 2] > 'foo' = ", [1, 2] > 'foo'
print "(1, 2) > 'foo' = ", (1, 2) > 'foo'
print "[1, 2] > (1, 2) = ", [1, 2] > (1, 2)
这样的比较能得到结果,是c/c艹程序员想都不敢想的。但python2就能得到结果
[1, 2] > 'foo' = False
(1, 2) > 'foo' = True
[1, 2] > (1, 2) = False
在跑一趟好哦你3中
print("[1, 2] > 'foo' = ", [1, 2] > 'foo')
print("(1, 2) > 'foo' = ", (1, 2) > 'foo')
print("[1, 2] > (1, 2) = ", [1, 2] > (1, 2))
会抛出异常
---------------------------------------------------------------------------
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()
python3的input函数也有所改变,它把把接收的数据都当成str
处理。而在python中,我们还需要raw_input()来解决这个问题
python2代码
>>> 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'>
python3代码
>>> my_input = input('enter a number: ')
enter a number: 123
>> type(my_input) <class 'str'>
在python2总我们广泛的使用xrange()
来做迭代,通常情况下xrange()
会比range()
快一点,但是python3中取消了xrange()
。
比如函数如下
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
在python2中调用
print '\ntiming range()'
%timeit test_range(n)
print '\n\ntiming xrange()'
%timeit test_xrange(n)
得到输出
timing range()
1000 loops, best of 3: 433 µs per loop
timing xrange()
1000 loops, best of 3: 350 µs per loop
在python3中调用
print('\ntiming range()')
%timeit test_range(n)
输出
timing range()
1000 loops, best of 3: 520 µs per loop