Python3 和 Python2 区别总结

hresh 326 0

Python3 和 Python2 区别总结

前言

Python 的 3​​.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python3 在设计的时候没有考虑向下相容。许多针对早期 Python 版本设计的程式都无法在 Python3 上正常执行。

为了照顾现有程序,Python 2.6 作为一个过渡版本,基本使用了 Python2 的语法和库,同时考虑了向 Python3 的迁移,允许使用部分 Python3 的语法与函数。

随着 Python 语言市场份额的增长,第三方库都正在努力地相容Python 3.x版本,所以如果想要学习 Python 的朋友们,最好从 Python3 开始学起,虽然 Python2 慢慢将淡出市场,但是我们还是有必要了解两者之间的区别。

区别

1.print 函数

print 语句没有了,取而代之的是 print() 函数。

Old: print "The answer is", 2*2
New: print("The answer is", 2*2)

Old: print x,           # Trailing comma suppresses newline
New: print(x, end=" ")  # Appends a space instead of a newline

Old: print              # Prints a newline
New: print()            # You must call the function!

Old: print >>sys.stderr, "fatal error"
New: print("fatal error", file=sys.stderr)

Old: print (x, y)       # prints repr((x, y))
New: print((x, y))      # Not the same as print(x, y)!

2.整除

Python2 中 / 的结果是整型,Python3 中是浮点类型。

Python2:

>>> 1 / 2
0
>>> 1.0 / 2.0
0.5

Python3:

>>> 1/2
0.5

3.Unicode

Python2 默认编码是 ASCII,在使用 Python2 的过程中经常会遇到编码问题,当时因为 Python 语言还没使用 Unicode,所以使用 ASCII 作为默认编码。Python3 默认编码是 Unicode(utf-8),也就不需要在文件头部写 # coding=utf-8。

Python2:

>>> str = "我爱北京天安门"
>>> str
'\xe6\x88\x91\xe7\x88\xb1\xe5\x8c\x97\xe4\xba\xac\xe5\xa4\xa9\xe5\xae\x89\xe9\x97\xa8'
>>> sys.getdefaultencoding()
'ascii'

Python3:

>>> str = "我爱北京天安门"
>>> str
'我爱北京天安门'
>>> sys.getdefaultencoding()
'utf-8'

4.迭代器

在 Python2 中很多返回列表对象的内置函数和方法在 Python3 都改成了返回类似于迭代器的对象,因为迭代器的惰性加载特性使得操作大数据更有效率。Python2 中的 xrange 在 Python3 中重命名为 range。

Python2:

>>> [x for x in xrange(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Python3:

>>> [x for x in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [x for x in xrange(10)]

NameError                                 Traceback (most recent call last)
<ipython-input-2-4ecef59b8e55> in <module>()
----> 1 [x for x in xrange(10)]

NameError: name 'xrange' is not defined

另外,字典对象的 dict.keys()、dict.values() 方法都不再返回列表,而是以一个类似迭代器的 "view" 对象返回。
Python2:

>>>dic1={'a':1,'b':2,'c':3,'d':4,'e':5}
>>>dic1.keys()
>>>dic1.values()
['a', 'c', 'b', 'e', 'd']
[1, 3, 2, 5, 4]

Python3:

>>>dic1={'a':1,'b':2,'c':3,'d':4,'e':5}
>>>dic1.keys()
>>>dic1.values()
dict_keys(['a', 'b', 'c', 'd', 'e'])
dict_values([1, 2, 3, 4, 5])

高阶函数 map、filter、zip 返回的也都不是列表对象了,对于比较高端的 reduce 函数,它在 Python 3.x 中已经不属于 built-in 了,被挪到 functools 模块当中。

Python2:

#类型是 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]

Python3:

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

map、filter 从函数变成了类,其次,它们的返回结果也从当初的列表成了一个可迭代的对象, 我们尝试用 next 函数来进行手工迭代。

>>> f =filter(lambda x:x %2 ==0, range(10))
>>> next(f)
0
>>> next(f)
2

5.不等运算符

Python2 中不等于有两种写法 != 和 <>;Python3 中去掉了 <>, 只有 != 一种写法,我并未使用过 <>。

6.数据类型

Python3 去除了 long 类型,现在只有一种整型——int,但它的行为就像 Python2 版本的 long;

新增了 bytes 类型,对应于 Python2 版本的八位串

7.True和False

True 和 False 在 Python2 中是两个全局变量(名字),在数值上分别对应 1 和 0,既然是变量,那么就可以重新指向其它对象。

>>> False = '1'
>>> False
'1'
>>> if False:
...     print("?")
... 
?

Python3 修正了这个缺陷,True 和 False 变为两个关键字,永远指向两个固定的对象,不允许再被重新赋值。

>>> True = 1
  File "<stdin>", line 1
  SyntaxError: can't assign to keyword

7.nonlocal

global 适用于函数内部修改全局变量的值,但是在嵌套函数中,想要给一个变量声明为非局部变量是没法实现的,在 Python3 中,新增了关键字 nonlcoal,使得非局部变量成为可能。

Python2:

def func():
    c = 1
    def foo():
        nonlocal c
        c = 12
    foo()
    print(c)
func() 
 File "<ipython-input-10-441055e26d24>", line 4
    nonlocal c
             ^
SyntaxError: invalid syntax

Python3:

def func():
    c = 1
    def foo():
        nonlocal c
        c = 12
    foo()
    print(c)
func() #12

8.通过input()解析用户的输入

在 python2 中 raw_input() 和 input(),两个函数都存在,其中区别为:raw_input()---将所有输入作为字符串看待,返回字符串类型; input()-----只能接收"数字"的输入,在对待纯数字输入时具有自己的特性,它返回所输入的数字的类型(int, float )。

在 python3 中 raw_input() 和 input() 进行了整合,去除了 raw_input(),仅保留了 input() 函数,其接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型。

9.异常

except 关键字的使用在 Python 3 中处理异常也轻微的改变了,在 Python 3 中我们现在使用 as 作为关键词。

Python2:

print 'Python', python_version()
try:
    let_us_cause_a_NameError
except NameError, err:
    print err, '--> our error message'


Python 2.7.6
name 'let_us_cause_a_NameError' is not defined --> our error message

Python3:

print('Python', python_version())
try:
    let_us_cause_a_NameError
except NameError as err:
    print(err, '--> our error message')


Python 3.4.1
name 'let_us_cause_a_NameError' is not defined --> our error message

raise 语句使用逗号将抛出对象类型和参数分开,3.x取消了这种奇葩的写法,直接调用构造函数抛出对象即可。

9.For 循环变量和全局命名空间泄漏

在 Python3 中 for 循环变量不会再导致命名空间泄漏。

"列表推导不再支持 [... for var in item1, item2, ...] 这样的语法。使用 [... for var in (item1, item2, ...)] 代替。也需要提醒的是列表推导有不同的语义:  他们关闭了在 `list()` 构造器中的生成器表达式的语法糖, 并且特别是循环控制变量不再泄漏进周围的作用范围域."

Python2:

print 'Python', python_version()

i = 1
print 'before: i =', i

print 'comprehension: ', [i for i in range(5)]

print 'after: i =', i


Python 2.7.6
before: i = 1
comprehension:  [0, 1, 2, 3, 4]
after: i = 4

Python3:

print('Python', python_version())

i = 1
print('before: i =', i)

print('comprehension:', [i for i in range(5)])

print('after: i =', i)


Python 3.4.1
before: i = 1
comprehension: [0, 1, 2, 3, 4]
after: i = 1

10.继承

class A:
     def __init__(self):
         print("A")

class B(A):
     pass


class C(A):
    def __init__(self):
        print("C")

class D(B,C):
    pass

d1 = D()

Python2 结果为 A,Python3 结果为 C。

python2 的继承顺序是 D -> B -> A -> C 深度优先
python3 的继承顺序是 D -> B -> C -> A 广度优先

发表评论 取消回复
表情 图片 链接 代码

分享