Python3与Python2的具体区别

2020-08-04 16:18:51 浏览数 (1)

前言

有赞的数据库管控平台是基于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'>
print

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-

0 人点赞