Python2.x 与 3.x 版本区别
新Python程序建议现在都写Python3版本语法。目前不支持 Python 3.0 的第三方库有 Twisted, py2exe, PIL等。即使无法立即使用 Python 3.0,也建议编写相容 Python 3.0 版本的程式,然后使用 Python 2.6, Python 2.7 来执行。Python 3.0 的变化主要在以下几个方面:
print 函数:
print 语句没有了,取而代之的是 print() 函数。
如果 Python2.x 版本想使用使用 Python3.x 的 print 函数,可以导入 future 包,该包禁用 Python2.x 的 print 语句,采用 Python3.x 的 print 函数:
>>> list =["a", "b", "c"]
>>> print list # python2.x 的 print 语句
['a', 'b', 'c']
>>> from __future__ import print_function # 导入 __future__ 包
>>> print list # Python2.x 的 print 语句被禁用,使用报错
File "<stdin>", line 1
print list
^
SyntaxError: invalid syntax
>>> print (list) # 使用 Python3.x 的 print 函数
['a', 'b', 'c']
>>>
Python3.x 与 Python2.x 的许多兼容性设计的功能可以通过 future 这个包来导入。
Unicode:
在 Python 3,我们最终有了 Unicode (utf-8) 字符串,以及一个字节类:byte 和 bytearrays。由于 Python3.x 源码文件默认使用 utf-8 编码,所以使用中文就更加方便了。
除法运算:
Python 中的除法有两个运算符,/
和 //
这里只说 /
除法,因为 //
在Python2和3版本中是一样的。
在 Python 2.x 中,整数相除的结果是一个整数,把小数部分完全忽略掉,浮点数除法会保留小数点的部分得到一个浮点数的结果。
Python 2.x:
>>> 1 / 2
0
>>> 1.0 / 2.0
0.5
Python 3.x:
>>> 1/2
0.5
异常:
在 Python 3 中我们现在使用 as 作为关键词。
捕获异常的语法由 except exc, var 改为 except exc as var。使用语法except (exc1, exc2) as var 可以同时捕获多种类别的异常。 Python 2.6 已经支持这两种语法。
- 在 2.x 时代,所有类型的对象都是可以被直接抛出的,在 3.x 时代,只有继承自BaseException的对象才可以被抛出。
- 2.x raise 语句使用逗号将抛出对象类型和参数分开,3.x 取消了这种奇葩的写法,直接调用构造函数抛出对象即可。
xrange:
在 Python 3 中,range() 是像 xrange() 那样实现以至于一个专门的 xrange() 函数都不再存在(在 Python 3 中 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
Python 2
print 'Python', python_version()
print '\ntiming range()'
%timeit test_range(n)
print '\n\ntiming xrange()'
%timeit test_xrange(n)
Python 2.7.6
timing range()
1000 loops, best of 3: 433 µs per loop
timing xrange()
1000 loops, best of 3: 350 µs per loop
Python3
print('Python', python_version())
print('\ntiming range()')
%timeit test_range(n)
Python 3.4.1
timing range()
1000 loops, best of 3: 520 µs per loop
print(xrange(10))
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-5-5d8f9b79ea70> in <module>()
----> 1 print(xrange(10))
NameError: name 'xrange' is not defined
八进制字面量表示:
八进制数必须写成0o777,原来的形式0777不能用了;二进制必须写成0b111。
新增了一个bin()函数用于将一个整数转换成二进制字串。 Python 2.6已经支持这两种语法。
在Python 3.x中,表示八进制字面量的方式只有一种,就是0o1000。
python 2.x
>>> 0o1000
512
>>> 01000
512
python 3.x
>>> 01000
File "<stdin>", line 1
01000
^
SyntaxError: invalid token
>>> 0o1000
512
不等运算符:
Python 2.x中不等于有两种写法 != 和 <>
Python 3.x中去掉了<>, 只有!=一种写法
去掉了repr表达式``:
Python 2.x 中反引号``相当于repr函数的作用
Python 3.x 中去掉了``这种写法,只允许使用repr函数,这样做的目的是为了使代码看上去更清晰么?不过我感觉用repr的机会很少,一般只在debug的时候才用,多数时候还是用str函数来用字符串描述对象。
def sendMail(from_: str, to: str, title: str, body: str) -> bool:
pass
多个模块被改名(根据PEP8):
旧名字 | 新名字 |
---|---|
_winreg | winreg |
ConfigParser | configparser |
copy_reg | copyregg |
Queue | queue |
SocketServer | socketserver |
repr | reprlib |
StringIO模块现在被合并到新的io模组内。 new, md5, gopherlib等模块被删除。 Python 2.6已经支援新的io模组。
httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib被合并到http包内。
取消了exec语句,只剩下exec()函数。 Python 2.6已经支援exec()函数。
数据类型:
- Py3.X去除了long类型,现在只有一种整型——int,但它的行为就像2.X版本的long
- 新增了bytes类型,对应于2.X版本的八位串,定义一个bytes字面量的方法如下:
>>> b = b'china'
>>> type(b)
<type 'bytes'>
str 对象和 bytes 对象可以使用 .encode() (str -> bytes) 或 .decode() (bytes -> str)方法相互转化。
>>> s = b.decode()
>>> s
'china'
>>> b1 = s.encode()
>>> b1
b'china'
- dict的.keys()、.items 和.values()方法返回迭代器,而之前的iterkeys()等函数都被废弃。同时去掉的还有 dict.has_key(),用 in替代它吧 。
打开文件:
原:
file( ..... )
或
open(.....)
改为只能用
open(.....)
从键盘录入一个字符串:
原:
raw_input( "提示信息" )
改为:
input( "提示信息" )
在python2.x中raw_input()和input( ),两个函数都存在,其中区别为:
raw_input(): 将所有输入作为字符串看待,返回字符串类型
input(): 只能接收"数字"的输入,在对待纯数字输入时具有自己的特性,它返回所输入的数字的类型(int, float )
在python3.x中raw_input()和input( )进行了整合,去除了raw_input(),仅保留了input()函数,其接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型。
map、filter 和 reduce:
这三个函数号称是函数式编程的代表。在 Python3.x 和 Python2.x 中也有了很大的差异。
首先我们先简单的在 Python2.x 的交互下输入 map 和 filter,看到它们两者的类型是 built-in function(内置函数):
>>> map
<built-in function map>
>>> filter
<built-in function filter>
>>>
它们输出的结果类型都是列表:
>>> map(lambda x:x *2, [1,2,3])
[2, 4, 6]
>>> filter(lambda x:x %2 ==0,range(10))
[0, 2, 4, 6, 8]
>>>
但是在Python 3.x中它们却不是这个样子了:
>>> map
<class 'map'>
>>> map(print,[1,2,3])
<map object at 0x10d8bd400>
>>> filter
<class 'filter'>
>>> filter(lambda x:x % 2 == 0, range(10))
<filter object at 0x10d8bd3c8>
>>>
首先它们从函数变成了类,其次,它们的返回结果也从当初的列表成了一个可迭代的对象, 我们尝试用 next 函数来进行手工迭代:
>>> f =filter(lambda x:x %2 ==0, range(10))
>>> next(f)
0
>>> next(f)
2
>>> next(f)
4
>>> next(f)
6
>>>
对于比较高端的 reduce 函数,它在 Python 3.x 中已经不属于 built-in 了,被挪到 functools 模块当中。