声明:由于博主主要用的是Python3.5,所以文中可能出现一些纰漏,敬请谅解,也可以向我提出来。
十点区别
一、print
print几乎是每种编程语言必须有的,Python也不例外,而且Python2和Python3最大的区别之一就是print。在Python2中,print是一个关键字,如下:1
2
3
4import keyword
keyword.kwlist
['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
>>>
而在Python3中,print是一个函数,因此Python3中print都需要加上括号表示函数,如下:1
2
3
4
5
6
7
8
9
10
11
12print) help(
Help on built-in function print in module builtins:
print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
其中value就是要打印的字符串,sep=’ ‘表示默认用空格隔开,end=’\n’表示默认换行。
例子:
end:1
2'hello', end='') print(
hello>>> print('world')
注:Python2不换行只需要用一个逗号,
隔开。
sep:1
2
3
4'hello', 'world') print(
hello world
'hello', 'world', sep=',') print(
hello,world
二、输入函数
在Python2中,输入函数有两种:input()
和raw_input()
1
2
3
4
5
6
7
8
9'input what you want to do:') something = input(
input what you want to do:'play basketball'
print something
play basketball
'input what you want to do:') something = raw_input(
input what you want to do:'do sports'
print something
'do sports'
而在Python3中,只保留了input()
函数。
三、异常处理
相比较Python2,Python3在异常处理方面改动得比较多,比如:
1.异常的继承:在Python2中,在所有类型的对象只要发生异常时就抛出,不需要继承BaseException;而在Python3中,只有继承自BaseException的对象才可以被抛出,更加严格规范。
2.异常的语法:
在Python2中,异常可以写成:1
2
3
4try:
10/0
except Exception, e:
print 'Error', e
在Python3中,异常则必须加上as
,不然会有语法错误,写成:1
2
3
4try:
10/0
except Exception as e:
print('Error', e)
因此,我们当然建议Python3这种具有比较规范的编码风格的写法。
3.异常的捕获:
在Python2中,异常捕获写成raise Exception, args
1
2
3
4try:
10/0
except Exception, e:
raise ValueError, e
在Python3中,异常捕获可以写成raise Exception(args)
1
2
3
4try:
10/0
except Exception as e:
raise ValueError(e)
四、字符串
Python3中,字符串总是由str类型表示,二进制数据则由bytes类型表示。
1.编码问题:
在Python2中,默认编码是ASCII:1
2
3import sys
print sys.getdefaultencoding()
ascii
而在Python3中,默认编码是utf-8:1
2
3import sys
print (sys.getdefaultencoding())
utf-8
2.字符串类型
在Python2中,字符串类型有两种,为str类型和unicode类型:1
2
3
4
5
6
7
8
9
10
11'你好' s1 =
type(s1)
<type 'str'>
u'你好' s2 =
type(s2)
<type 'unicode'>
b'你好' s3 =
type(s3)
<type 'str'>
而在Python3中,字符串类型只有str类型,外加一个bytes类型,主要用来处理二进制数据:1
2
3
4
5
6
7
8
9
10
11'你好' s1 =
type(s1)
<class 'str'>
>>> s2 = u'你好'
type(s2)
<class 'str'>
>>> s3 = b'china'
type(s3)
<class 'bytes'>
3.str和bytes的相互转化
str类型和bytes类型可以利用encode()
和decode()
函数相互转化:1
2
3
4
5
6
7
8
9
10
11
12
13
14b'I love Python' b =
type(b)
<class 'bytes'>
>>> s = b.decode()
type(s)
<class 'str'>
>>> print(s)
I love Python
>>> b = s.encode()
type(b)
<class 'bytes'>
>>> print(b)
b'I love Python'
五、运算符
1.不等运算符:
在Python2中,不等符号可以用!=
或者<>
表示:1
2
3
42<>3
True
2<>2
False
在Python3中,只有一个不等运算符!=
1
2
3
42 != 3
True
2 != 2
False
2.类型比较:
在Python2中,如果遇到两个不同类型的变量相互比较,仍然会返回bool结果:1
2
3
41] < 2 [
False
1] > 2 [
True
上述一个是list,一个是int,然而比较后Python2仍然会给出一个bool结果。
而在Python3中,遇到这种情况时会直接抛出类型不匹配异常:1
2
3
41] < 2 [
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: list() < int()
3.除法运算
在Python2中,做除法运算时只返回整数部分:1
23/2
1
若要保留小数,则必须import division
,如下:1
2
3from __future__ import division
3/2
1.5
若要保留小数点后两位,要利用round()
函数,如下:1
2
3
43/2, 2) round(
1.5
5/3, 2) round(
1.67
而在Python3中,做除法运算时返回浮点数:1
2
3
43/2
1.5
4/2
2.0
若要取整,利用运算符//
:1
25//3
1
若要保留两位有效数字,则利用round()
函数,如下:1
25/3, 2) round(
1.67
六、赋值
在Python2中,下面这种写法是错误的:1
2
3
4
51,2,3,4] a,b,*res = [
File "<stdin>", line 1
a,b,*res = [1,2,3,4]
^
SyntaxError: invalid syntax
而在Python3中,这种写法是正确的,res自动匹配剩余的变量,形成一个list,如下:1
2
3
4
5
61,2,3,4] a,b,*res = [
print(res)
[3, 4]
type(res)
<class 'list'>
>>>
七、高阶函数
在Python2中,zip()
,map()
和filter()
这三个函数直接返回列表list;1
2
3
4
5
61,2,3] s1 = [
'a','b','c'] s2 = [
print zip(s1,s2)
[(1, 'a'), (2, 'b'), (3, 'c')]
type(zip(s1,s2))
<type 'list'>
而在Python3中,zip()
,map()
和filter()
这三个函数直接返回迭代器,若要变成列表,需要在前面加上list做类型转换。1
2
3
4
5
6
71,2,3] s1 = [
'a','b','c'] s2 = [
print(zip(s1,s2))
<zip object at 0x00000228B1B44E88>
print(list(zip(s1,s2)))
[(1, 'a'), (2, 'b'), (3, 'c')]
>>>
八、range/xrange函数
在Python2中,range()
函数返回一个列表list,而xrange()
函数一般用来创建迭代对象,如下:1
2
3
4
5
6print range(3)
[0, 1, 2]
print [x for x in xrange(5)]
[0, 1, 2, 3, 4]
print list(xrange(5))
[0, 1, 2, 3, 4]
而在Python3中,只有range()
函数,而且这个range函数是类似于xrange函数的,因为具有迭代功能,如下:1
2
3
45)) print(range(
range(0, 5)
5))) print(list(range(
[0, 1, 2, 3, 4]
一点思考:这里我觉得做这样的改变是为了节省内存,比如:在Python2中,range(1000)返回的是一个列表,一下子生成了一个长度为1000的内存空间,而Python3中range(1000)返回的是一个迭代器,需要用到时我们再遍历即可,从而节省了内存空间。
九、生成器函数
在Python2中,生成器函数需要生成另外一个生成器生成的值,一般需要嵌套的值:1
2
3
4
5
6
7
8
9def chain(*iterable):
for it in iterable:
for each in it:
yield each
s = 'abc'
m = [1,2,3]
print list(chain(s, m))
>>>['a', 'b', 'c', 1, 2, 3]
而在Python3中,添加了一个yield from
,可以简化这种操作,生成器函数自动把操作交给可以接收到的各个迭代对象处理:1
2
3
4
5
6
7
8def chain(*iterable):
for it in iterable:
yield from it
s = 'abc'
m = [1,2,3]
print(list(chain(s, m)))
>>>['a', 'b', 'c', 1, 2, 3]
十、类
在Python2中,子类继承父类经常要写super()
函数,就是子类初始化时需要初始化父类,super()
函数要带一些参数,如下:1
2
3
4
5
6
7
8
9
10
11class Parent(object):
def __init__(self):
self.a = 100
class Child(Parent):
def __init__(self):
super(Child, self).__init__()
c = Child()
print c.a
>>>100
而在Python3中,可省略super()
函数里面的参数,如下:1
2
3
4
5
6
7
8
9
10class Parent(object):
def __init__(self):
self.a = 100
class Child(Parent):
def __init__(self):
super().__init__()
c = Child()
print(c.a)
其他区别
一、模块名字
改动了一些模块的名字:1
2
3
4
5
6_winreg->winreg
ConfigParser->configparser
copy_reg->copyreg
Queue->queue
SocketServer->socketserver
repr->reprlib
二、exec语句
取消了exec语句,保留了exec()
函数,其实Python2.7已经支持exec()
函数了。
三、模块改动
1 | string.letters |
一点建议
如果是Python菜鸟,我建议直接学习使用Python3,因为Python3是大势所趋,许多模块或库都已不再支持Python2. 如果是已经上手了Python2的同学,也不必太过纠结要不要弃2从3,因为语言只是一种工具,要思考背后的东西,透过现象看本质才是最重要的。