Dantangfan

python2.7.x和python3.x的简单区别

许多python初学者都在为难到底是选择python2还是python3,我刚刚学python的时候也有这个疑问。大佬们各有个的说法,但学完基础之后,我觉得你选一个适合自己的就是最好的了,看哪个爽就学哪个。开源东西没有专门维护和标准,果然还是够但疼。

我觉得也没有什么好坏之分,简单了解了之后,你会发现他们支持的库已经基本差不太多了。这里就简单的说说两个版本的一些区别,以免后面东西学咋了就什么都忘了。

__future__模块

这应该是python中最有用的模块之一了,虽然python3中有一些python2不支持的关键字和特性,但他们都可以在python2的__future__中找到。所以如果你打算在你的python2中体验python3语言的特性,就可以简单通过导入__future__模块。比如说我们想在python2中使用python3的整除算法,可以这样做

from __future__ import division

当然,__future__并不是专门为从python2跨越到python3准备的,它只是提供了向后兼容,也就是说python2.1中的__future__可以导入python2.2的特性,以此类推。

更多的__future__特性可以从官方文档中看到

print函数

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

才能得到正确的输出

except

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

这是一个很棒的改进,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()

input

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

xrange()

在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

不断继续补充中。。。。。




blog comments powered by Disqus