首頁技術(shù)文章正文

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

更新時間:2018-10-31 來源:黑馬程序員 瀏覽量:

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

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

  future模塊

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

  from__future__importdivision

  更多的__future__模塊可被導(dǎo)入的特性被列在下表中:

  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函數(shù)

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

  Python 2 不具有額外的小括號問題。但對比一下,如果我們按照 Python 2 的方式不使用小括號調(diào)用print函數(shù),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 中是一個聲明,而不是一個函數(shù)調(diào)用。

  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)或者是列表/集合/字典推導(dǎo)式。

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

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

  在 Python 3 中,range()是像xrange()那樣實現(xiàn)以至于一個專門的xrange()函數(shù)都不再存在(在 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 中顯著的整數(shù)和布爾類型。

  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的結(jié)果,當(dāng)它使一個整數(shù)類型,而不是浮點類型的時候,你可以看到執(zhí)行查找的速度是 60000 倍快。盡管如此,因為 Python 2.x 的range或者是xrange沒有一個__contains__方法,這個整數(shù)類型或者是浮點類型的查詢速度不會相差太大。

  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 中的證據(jù):

  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()之間的速度不同。因為他們是用相同的方法實現(xiàn)的,因此期望相同的速度。盡管如此,這事實在于 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




作者:黑馬程序員人工智能+Python培訓(xùn)學(xué)院
首發(fā):http://python.itheima.com

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