Python2 和 Python3
最近在面试, 遇到了几个同样的问题, 就是 “python2 和 python3 具体有哪些区别”? 遇到这个问题的时候, 我每次都懵逼, 因为确实除了语法糖以外的区别, 我一个都说不出来. 所以回来之后查了一下资料, 总结出几个主要的区别, 记录下来.
“future” 模块
python3 引入了一些python2 没有的关键字和功能, 如果需要在python2中使用这些功能, 就需要导入__future__
模块. 举个例子, 在python3中/
是返回一个浮点数, 但是在python2中, 除法操作返回的是一个整数. 如果要在python2中使用python3的除法功能, 就需要引入 __future__
模块来支持.
1 | python 2.7 |
“print” 语法糖
在python2的语法当中, 如果需要在屏幕上打印的时候, 仅仅需要pring "something"
. 但是来到python3, 这个函数被print()
替代了.
python2
1 | print 'Python', python_version() |
输出1
2
3
4Python 2.7.6
Hello, World!
Hello, World!
text print more text on the same line
python3
1 | print('Python', python_version()) |
输出1
2
3Python 3.4.1
Hello, World!
some text, print more text on the same line
整数除法
整数除法对于python2到python3转换是一个大坑
python2
1 | print 'Python', python_version() |
输出1
2
3
4
5Python 2.7.6
3 / 2 = 1
3 // 2 = 1
3 / 2.0 = 1.5
3 // 2.0 = 1.0
python3
1 | print('Python', python_version()) |
输出1
2
3
4
5Python 3.4.1
3 / 2 = 1.5
3 // 2 = 1
3 / 2.0 = 1.5
3 // 2.0 = 1.0
Unicode
python2 有ASCII str()
类型, 跟unicode()
类型并不一样, 而且在python2中没有byte
类型.
python3 有utf-8 的 str()
类型. 同时python3也用byte
和 bytearray
Python2
1 | >>>print 'Python', python_version() |
Python3
1 | >>>print('Python', python_version()) |
xrange
在python2, xrange()
主要被用来构建一个可迭代对象, 实现起来跟generator非常像. 但是xrange
并不是有限的, 开发者可以无限地迭代下去. 而在python3, xrange()
不复存在了, 取而代之的是 range()
这个函数. 如果在python3中调用xrange()
, 会被抛一个NameError
的异常.
1 | n = 10000 |
对于上面的这个简单的程序, py2和py3各自有着不同的表现.
Python2
1 | print '\ntiming range()' |
Python3
1 | print("\ntiming range()") |
再有就是, 在python3中, range
对象有一个新的字段, 叫__contains__
, 对于判断一个元素是否存在于range
能加速(前提是int或者boolean).
1 | x = 10000000 |
从上面的结果来看, 如果元素是整数而不是float的话, 速度要快非常非常多.
抛出异常
python2和python3抛出异常的差异, 仅仅存在于语法层面.
python2
1 | print 'Python, python_version()' |
python3
1 | raise IOError, "file error" |
异常处理
既然py2和py3在抛出异常上有语法上的差别, 那么处理异常方面也同样会有一点点语法上的区别.
python2
1 | try: |
python3
1 | try: |
next() 和 .next()
在python3当中, .next()
方法已经被取消了, 只剩下next()
方法可用. python2 两个方法都继续存在. 如果在python3中调用.nxt()
, 系统会抛出异常.
for循环变量和全局空间泄露
python3对比python2的一个重大改变要数python3中, for循环的变量并不会被泄露到全局空间里. 官方文档是这么描述的
“List comprehensions no longer support the syntactic form [… for var in item1, item2, …]. Use [… for var in (item1, item2, …)] instead. Also note that list comprehensions have different semantics: they are closer to syntactic sugar for a generator expression inside a
list()
constructor, and in particular the loop control variables are no longer leaked into the surrounding scope.”
python2
1 | i = 1 |
pythnon3
1 | i = 1 |
比较不可排序类型
作为python3的重大改进之一, 就是当开发者在试图比较两个不可排序的类型时, 系统会抛出TypeError
的异常. 那么什么是不可排序变量呢? 举个例子, 当用list
和str()
比较, 就是一个不可排序类型的比较.
处理用户输入
在python中, 如果要处理用户的输入, 最常使用的方法是input()
. 但是很多开发者不知道的是, 在python2当中, input()
所返回的类型并不是固定的, 为了避免一些危险的操作出现, 有经验的python2开发会使用raw_input()
而不是input()
. 但是, 在python3中, input()
的返回类型终于被固定了, 在python3的各个版本当中, inpit()
返回的是一个str
对象.
python2
1 | my_input = input('enter number: ') |
pythnon3
1 | my_input = input('enter number: ') |