前言
有赞的数据库管控平台是基于Python 2(py2)开发的,目前已经升级到python3(py3) 版本,主程序基于python 3.6.x。写本文是梳理一下 两个版本之间的语法,函数等差异。
py3 与py2 大多数不兼容的地方主要是:移除二义性和错误修正。可以理解为py3 总体上更加严格和准确。
数据类型
在数值方面 py3 移除long类型,只保留一种整型——int,但它的行为就像2.X版本的long 类型一样。
py2
代码语言:javascript复制In [101]: a=2**64
In [102]: type(a)
Out[102]: long
py3
代码语言:javascript复制>>> a=2**64
>>> type(a)
<class 'int'>
Python3中print为一个函数,使用时必须用括号括起来;Python2中print为class
python 2
代码语言:javascript复制In [1]: print "hello python 3"
hello python 3
In [2]: print ("hello python 3")
hello python 3
In [9]: print("hello", "world")
('hello', 'world') ##输出元组
python 3
代码语言:javascript复制>>> print("hello python 3")
hello python 3
>>> print "hello python 3"
File "<stdin>", line 1
print "hello python 3"
^
SyntaxError: Missing parentheses in call to 'print'
>>> print("hello", "world")
hello world ##没有 逗号
在 python2 中,print语句后面接的是一个元组对象,而在 python3 中,print 函数可以接收多个位置参数。
编码
py2 中的默认编码是ASCII 码,py3 默认编码是 Unicode(utf-8),带来的一个好处是我们不需要在文件头部写 # coding=utf-8 了。
py2
代码语言:javascript复制In [10]: import sys
In [11]: sys.getdefaultencoding()
Out[11]: 'ascii'
py3
代码语言:javascript复制>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
py2
代码语言:javascript复制In [17]: str = "我爱北京天安门"
In [18]: str
Out[18]: 'xe6x88x91xe7x88xb1xe5x8cx97xe4xbaxacxe5xa4xa9xe5xaex89xe9x97xa8'
In [19]: str = u"我爱北京天安门"
In [20]: str
Out[20]: u'u6211u7231u5317u4eacu5929u5b89u95e8'
py3
代码语言:javascript复制>>> str = "我爱北京天安门"
>>> str
'我爱北京天安门'
字符串类型
py2 中字符串有两种类型,一个是unicode 文本字符,一个是 str 表示字节序列。在py3 中做了严格的控制str表示字符串,byte表示字节序列。任何需要写入文本,shell命令的结果或者网络传输的数据都只接收字节序列 ,需要进一步decode/encode处理才能使用,这点很重要。
py3
代码语言:javascript复制>>> print("默认字符集为:%s" % (sys.getdefaultencoding()))
默认字符集为:utf-8
>>> str = "你好"
>>> print(len(str))
2
>>> str.encode()
b'xe4xbdxa0xe5xa5xbd'
>>> str.encode("utf-8")
b'xe4xbdxa0xe5xa5xbd'
>>> hello_utf8 = b'xe4xbdxa0xe5xa5xbd'
>>> hello_utf8.decode("utf-8")
'你好'
python 以 unicode 作为字符运算的基准。
bytes -- decode -- unicode -- encode -- bytes
Ture 和False
在 py2 中True和False是两个全局变量,我们可以为其赋值,但是在py3中,将其修改Wie两个关键字,不能对其赋值。
代码语言:javascript复制In [92]: False = '1'
In [93]: False
Out[93]: '1'
In [94]: if False:
...: print("?")
...:
?
py3
代码语言:javascript复制>>> False = '1'
File "<stdin>", line 1
SyntaxError: can't assign to keyword
文件操作
py2中 可以使用file() 和open() 函数打开文件,但是在py3中 只能通过open()函数来打开文件。
py2 中使用open(filename,'r') 打开文件,可以从文件头和末尾读取数据。 py3 中如果没有使用b模式选项打开的文件,只允许从文件头开始计算相对位置,从文件尾计算时就会引发异常.
py2
代码语言:javascript复制In [23]: fl= "/Users/yangyi/t"
In [24]: f=open(fl,'r')
In [26]: f.seek(-3,2)
py3
代码语言:javascript复制###从文件尾部读数据 报错
>>> fl= "/Users/yangyi/t"
>>> f=open(fl,'r')
>>> f.seek(-3,2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
io.UnsupportedOperation: can't do nonzero end-relative seeks
###从文件头开始
>>> f=open(fl,'r')
>>> f.seek(1,0)
1
>>> f.read()
'0.96.100.11 3300n10.96.100.11 3301n10.96.100.11 3302n'
除法/
Python2中 /表示根据除数被除数小数点位得到结果,%表示取余, // 表示结果取整除
Python3中/ 不管除数和被除数是整型还是浮点型,结果是浮点型 ;%表示取余,// 结果取整。
py2
代码语言:javascript复制In [13]: print '3 / 2 =', 3 / 2
3 / 2 = 1
In [14]: print '3 // 2 =', 3 // 2
3 // 2 = 1
In [15]: print '3 / 2.0 =', 3 / 2.0
3 / 2.0 = 1.5
In [16]: print '3 // 2.0 =', 3 // 2.0
3 // 2.0 = 1.0
py3
代码语言:javascript复制>>> print ('3 / 2 =', 3 / 2)
3 / 2 = 1.5
>>> print ('3 // 2 =', 3 // 2)
3 // 2 = 1
>>> print ('3 / 2.0 =', 3 / 2.0)
3 / 2.0 = 1.5
>>> print ('3 // 2.0 =', 3 // 2.0)
3 // 2.0 = 1.0
总结一下Python3 整形除法自动转为float。/表示除,%表示取余,//结果取整;Python2中带上小数点/表示真除,%表示取余,//结果取整
row_input() input()
在 py2 中 存在 raw_input() 和 input(),两个函数,其中raw_input()将所有输入作为字符串,返回字符串类型;input()只能接收"数字"的输入,在对待纯数字输入时具有自己的特性,它返回所输入的数字的类型(int, float )。
在py3 中 只保留input(),将任意输入当做字符串处理,并返回字符串
py2
代码语言:javascript复制In [105]: a=input(":")
:ab
----------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-105-b21f9789b594> in <module>()
----> 1 a=input(":")
<string> in <module>()
NameError: name 'ab' is not defined
In [106]: a=input(":")
:"ab"
In [107]: a
Out[107]: 'ab'
In [108]: type(a)
Out[108]: str
In [109]: a=input(":")
:11
In [110]: a
Out[110]: 11
In [111]: type(a)
Out[111]: int
py3
代码语言:javascript复制>>> s=input(" :")
:abc
>>>
>>> type(s)
<class 'str'>
>>> a=input(":")
:11
>>> type(a)
<class 'str'>
异常处理
在 Python 3 中使用 as 作为关键词。 捕获异常的语法由
except exc, var 改为 except exc as var。
使用语法except (exc1, exc2) as var可以同时捕获多种类别的异常。Python 2.6已经支持这两种语法。
py2
代码语言:javascript复制In [87]: try:
...: x=y
...: except NameError, err:
...: print "Something's wrong!"
...: print err
...:
Something's wrong!
name 'y' is not defined
py3
代码语言:javascript复制>>> try:
... x=y
... except NameError as err:
... print ("Something's wrong!")
... print (err)
...
Something's wrong!
name 'y' is not defined
迭代器
在 Python2 中很多返回列表对象的内置函数和方法在 Python3 都改成了返回类似于迭代器的对象,因为迭代器的惰性加载特性使得操作大数据更有效率,比如 py2 中的高阶函数 map、filter、zip 返回的也都不是列表对象而是类似迭代器的对象。
py2
代码语言:javascript复制>>> [x for x in xrange(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
py3
代码语言:javascript复制>>> [x for x in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [x for x in xrange(10)]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'xrange' is not defined
py2 中的 xrange 在 py3 中重命名为 range。py3中的xrange 被移除
字典对象的 dict.keys()、dict.values() 方法都不再返回列表,而是以一个类似迭代器的 "view" 对象返回。 py2
代码语言:javascript复制In [88]: dic1={'a':1,'b':2,'c':3,'d':4,'e':5}
In [89]: dic1.keys()
Out[89]: ['a', 'c', 'b', 'e', 'd']
In [90]: dic1.values()
Out[90]: [1, 3, 2, 5, 4]
In [91]: type(dic1.keys())
Out[91]: list
py3
代码语言:javascript复制>>> dic1={'a':1,'b':2,'c':3,'d':4,'e':5}
>>> dic1.keys()
dict_keys(['a', 'b', 'c', 'd', 'e'])
>>> dic1.values()
dict_values([1, 2, 3, 4, 5])
>>> type(dic1.keys())
<class 'dict_keys'>
不等运算符
Python 2.x中不等于有两种写法 != 和 <>。
Python 3.x中去掉了<>, 只有!=一种写法。
新增nonlocal 关键字
global 适用于函数内部修改全局变量的值,但是在嵌套函数中,想要给一个变量声明为非局部变量是没法实现的,在 Python3 中,新增了关键字 nonlcoal,使得非局部变量成为可能。
py2
代码语言:javascript复制In [103]: def func():
...: c = 1
...: def foo():
...: nonlocal c
...: c = 12
...: foo()
...: print(c)
File "<ipython-input-103-ba31cf925e9e>", line 4
nonlocal c
^
SyntaxError: invalid syntax
py3
代码语言:javascript复制>>> def func():
... c = 1
... def foo():
... nonlocal c
... c = 12
... foo()
... print(c)
...
>>> func()
12
小结
还有部分模块名称被修改,模块功能缩减,函数合并 ,大家可以网上搜索一下 或者看看参考文章。
总体切换到python3 的感触是,好的代码升级起来切换成本更少。欢迎读者朋友留言 你们遇到的升级过程中踩坑记录。
参考
https://www.zhihu.com/question/19698598
https://www.runoob.com/python/python-2x-3x.html
-The End-