Python 2.7.x 和 3.x 版本的重要区别(1)(2)
Python 3中的range对象中的__contains__方法
另一个值得一提的是,在Python 3.x中,range有了一个新的__contains__方法。__contains__方法可以有效的加快Python 3.x中整数和布尔型的“查找”速度。
- x = 10000000
- def val_in_range(x, val):
- return val in range(x)
- def val_in_xrange(x, val):
- return val in xrange(x)
- print('Python', python_version())
- assert(val_in_range(x, x/2) == True)
- assert(val_in_range(x, x//2) == True)
- %timeit val_in_range(x, x/2)
- %timeit val_in_range(x, x//2)
- Python 3.4.1
- 1 loops, best of 3: 742 ms per loop
- 1000000 loops, best of 3: 1.19 µs per loop
根据上面的timeit的结果,查找整数比查找浮点数要快大约6万倍。但由于Python 2.x中的range或xrange没有__contains__方法,所以在Python 2中的整数和浮点数的查找速度差别不大。
- print 'Python', python_version()
- assert(val_in_xrange(x, x/2.0) == True)
- assert(val_in_xrange(x, x/2) == True)
- assert(val_in_range(x, x/2) == True)
- assert(val_in_range(x, x//2) == True)
- %timeit val_in_xrange(x, x/2.0)
- %timeit val_in_xrange(x, x/2)
- %timeit val_in_range(x, x/2.0)
- %timeit val_in_range(x, x/2)
- Python 2.7.7
- 1 loops, best of 3: 285 ms per loop
- 1 loops, best of 3: 179 ms per loop
- 1 loops, best of 3: 658 ms per loop
- 1 loops, best of 3: 556 ms per loop
下面的代码证明了Python 2.x中没有__contain__方法:
- print('Python', python_version())
- range.__contains__
- Python 3.4.1
- <slot wrapper '__contains__' of 'range' objects
- print('Python', python_version())
- range.__contains__
- Python 2.7.7
- ---------------------------------------------------------------------------
- AttributeError Traceback (most recent call last)
- <ipython-input-7-05327350dafb> in <module>()
- 1 print 'Python', python_version()
- ----> 2 range.__contains__
- AttributeError: 'builtin_function_or_method' object has no attribute '__contains__'
- print('Python', python_version())
- xrange.__contains__
- Python 2.7.7
- ---------------------------------------------------------------------------
- AttributeError Traceback (most recent call last)
- in ()
- 1 print 'Python', python_version()
- ----> 2 xrange.__contains__
- AttributeError: type object 'xrange' has no attribute '__contains__'
关于Python 2中xrange()与Python 3中range()之间的速度差异的一点说明:
有读者指出了Python 3中的range()和Python 2中xrange()执行速度有差异。由于这两者的实现方式相同,因此理论上执行速度应该也是相同的。这里的速度差别仅仅是因为Python 3的总体速度就比Python 2慢。
- def test_while():
- i = 0
- while i < 20000:
- i += 1
- return
- print('Python', python_version())
- %timeit test_while()
- Python 3.4.1
- %timeit test_while()
- 100 loops, best of 3: 2.68 ms per loop
- print 'Python', python_version()
- %timeit test_while()
- Python 2.7.6
- 1000 loops, best of 3: 1.72 ms per loop
触发异常
Python 2支持新旧两种异常触发语法,而Python 3只接受带括号的的语法不然会触发SyntaxError):
Python 2
print 'Python', python_version()
Python 2.7.6
raise IOError, "file error"
--------------------------------------------------------------------------- IOError Traceback (most recent call last) <ipython-input-8-25f049caebb0> in <module>() ----> 1 raise IOError, "file error" IOError: file error
raise IOError("file error")
--------------------------------------------------------------------------- IOError Traceback (most recent call last) <ipython-input-9-6f1c43f525b2> in <module>() ----> 1 raise IOError("file error") IOError: file error
Python 3
print('Python', python_version())
Python 3.4.1
raise IOError, "file error"
File "<ipython-input-10-25f049caebb0>", line 1 raise IOError, "file error" ^ SyntaxError: invalid syntax The proper way to raise an exception in Python 3:
print('Python', python_version()) raise IOError("file error")
Python 3.4.1 --------------------------------------------------------------------------- OSError Traceback (most recent call last) <ipython-input-11-c350544d15da> in <module>() 1 print('Python', python_version()) ----> 2 raise IOError("file error") OSError: file error
异常处理
Python 3中的异常处理也发生了一点变化。在Python 3中必须使用“as”关键字。
Python 2
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
Python 3
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
评论关闭