首頁技術文章正文

Python入門之--Python 2.7.x 和 Python 3.x 的主要區(qū)別

更新時間:2018-09-28 來源:黑馬程序員技術社區(qū) 瀏覽量:

許多 Python 初學者想知道他們應該從 Python 的哪個版本開始學習。對于這個問題我的答案是 “你學習你喜歡的教程的版本,然后檢查他們之間的不同。"

但是如果你開始一個新項目,并且有選擇權?我想說的是目前沒有對錯,只要你計劃使用的庫 Python 2.7.x 和 Python 3.x 雙方都支持的話。盡管如此,當在編寫它們中的任何一個的代碼,或者是你計劃移植你的項目的時候,是非常值得看看這兩個主要流行的 Python 版本之間的差別的,以便避免常見的陷阱。

future模塊
Python 3.x 介紹的 一些Python 2 不兼容的關鍵字和特性可以通過在 Python 2 的內置__future__模塊導入。如果你計劃讓你的代碼支持 Python 3.x,建議你使用__future__模塊導入。例如,如果我想要 在Python 2 中表現 Python 3.x 中的整除,我們可以通過如下導入

from__future__importdivision

更多的__future__模塊可被導入的特性被列在下表中:

featureoptional inmandatory ineffect

nested_scopes2.1.0b12.2PEP 227: Statically Nested Scopes

generators2.2.0a12.3PEP 255: Simple Generators

division2.2.0a23.0PEP 238: Changing the Division Operator

absolute_import2.5.0a13.0PEP 328: Imports: Multi-Line and Absolute/Relative

with_statement2.5.0a12.6PEP 343: The “with” Statement

print_function2.6.0a23.0PEP 3105: Make print a function

unicode_literals2.6.0a23.0PEP 3112: Bytes literals in Python 3000

(Source:https://docs.python.org/2/library/future.html)

fromplatformimportpython_version


print函數
很瑣碎,而print語法的變化可能是最廣為人知的了,但是仍值得一提的是: Python 2 的print聲明已經被print()函數取代了,這意味著我們必須包裝我們想打印在小括號中的對象。

Python 2 不具有額外的小括號問題。但對比一下,如果我們按照 Python 2 的方式不使用小括號調用print函數,Python 3 將拋出一個語法異常(SyntaxError)。

Python 2

print'Python', python_version()print'Hello, World!'print('Hello, World!')print"text", ;print'print more text on the same line'

Python2.7.6Hello, World!Hello, World!textprintmore textonthe same line

Python 3

print('Python', python_version())print('Hello, World!')print("some text,", end="")print(' print more text on the same line')

Python3.4.1Hello, World!some text,printmore textonthe same line

print'Hello, World!'

File"", line1print'Hello, World!'^SyntaxError: invalid syntax

注意

以上通過 Python 2 使用Printing "Hello, World"是非常正常的,盡管如此,如果你有多個對象在小括號中,我們將創(chuàng)建一個元組,因為print在 Python 2 中是一個聲明,而不是一個函數調用。

print'Python', python_version()print('a','b')print'a','b'

Python2.7.7('a','b')a b

xrange
在 Python 2 中xrange()創(chuàng)建迭代對象的用法是非常流行的。比如: for 循環(huán)或者是列表/集合/字典推導式。

這個表現十分像生成器(比如?!岸栊郧笾怠保?。但是這個xrange-iterable是無窮的,意味著你可以無限遍歷。

由于它的惰性求值,如果你不得僅僅不遍歷它一次,xrange()函數 比range()更快(比如 for 循環(huán))。盡管如此,對比迭代一次,不建議你重復迭代多次,因為生成器每次都從頭開始。

在 Python 3 中,range()是像xrange()那樣實現以至于一個專門的xrange()函數都不再存在(在 Python 3 中xrange()會拋出命名異常)。

importtimeitn =10000deftest_range(n):returnforiinrange(n):passdeftest_xrange(n):foriinxrange(n):pass

Python 2

print'Python', python_version()print'\ntiming range()'%timeit test_range(n)print'\n\ntiming xrange()'%timeit test_xrange(n)Python2.7.6timing range()1000loops, bestof3:433μs perlooptiming xrange()1000loops, bestof3:350μs perloop

Python 3

print('Python', python_version())print('\ntiming range()')%timeit test_range(n)Python3.4.1timing range()1000loops, bestof3:520μs perloop

print(xrange(10))---------------------------------------------------------------------------NameError                                Traceback (most recentcalllast)in()----> 1 print(xrange(10))NameError: name'xrange'isnotdefined

Python 3 中的range對象的__contains__方法

另外一件值得一提的事情就是在 Python 3 中range有一個新的__contains__方法(感謝Yuchen Ying指出了這個),__contains__方法可以加速"查找"在 Python 3.x 中顯著的整數和布爾類型。

x =10000000defval_in_range(x, val):returnvalinrange(x)defval_in_xrange(x, val):returnvalinxrange(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)Python3.4.11loops, best of3:742ms per loop1000000loops, best of3:1.19μs per loop

基于以上的timeit的結果,當它使一個整數類型,而不是浮點類型的時候,你可以看到執(zhí)行查找的速度是 60000 倍快。盡管如此,因為 Python 2.x 的range或者是xrange沒有一個__contains__方法,這個整數類型或者是浮點類型的查詢速度不會相差太大。

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)Python2.7.71loops, bestof3:285ms perloop1loops, bestof3:179ms perloop1loops, bestof3:658ms perloop1loops, bestof3:556ms perloop

下面說下__contain__方法并沒有加入到 Python 2.x 中的證據:

print('Python', python_version())range.__contains__Python3.4.1

print 'Python', python_version()range.__contains__Python 2.7.7---------------------------------------------------------------------------AttributeError                            Traceback (most recentcalllast)in()1print'Python', python_version()----> 2 range.__contains__AttributeError:'builtin_function_or_method'object hasnoattribute'__contains__'

print 'Python', python_version()xrange.__contains__Python 2.7.7---------------------------------------------------------------------------AttributeError                            Traceback (most recentcalllast)in()1print'Python', python_version()----> 2 xrange.__contains__AttributeError: type object'xrange'hasnoattribute'__contains__'

**注意在 Python 2 和 Python 3 中速度的不同***

有些猿類指出了 Python 3 的range()和 Python 2 的xrange()之間的速度不同。因為他們是用相同的方法實現的,因此期望相同的速度。盡管如此,這事實在于 Python 3 傾向于比 Python 2 運行的慢一點。

deftest_while():i =0whilei <20000:        i +=1return

print('Python', python_version())%timeit test_while()Python3.4.1100loops, bestof3:2.68ms perloop

print'Python', python_version()%timeit test_while()Python2.7.61000loops, bestof3:1.72ms perloop   

本文版權歸黑馬程序員JavaEE學院所有,歡迎轉載,轉載請注明作者出處。謝謝!

作者:黑馬程序員python+人工智能培訓學院

首發(fā):http://python.itheima.com/?v2

分享到:
在線咨詢 我要報名
和我們在線交談!