更新時(shí)間:2018-10-31 來源:黑馬程序員 瀏覽量:
許多 Python 初學(xué)者想知道他們應(yīng)該從 Python 的哪個(gè)版本開始學(xué)習(xí)。對(duì)于這個(gè)問題我的答案是 “你學(xué)習(xí)你喜歡的教程的版本,然后檢查他們之間的不同。"
但是如果你開始一個(gè)新項(xiàng)目,并且有選擇權(quán)?我想說的是目前沒有對(duì)錯(cuò),只要你計(jì)劃使用的庫 Python 2.7.x 和 Python 3.x 雙方都支持的話。盡管如此,當(dāng)在編寫它們中的任何一個(gè)的代碼,或者是你計(jì)劃移植你的項(xiàng)目的時(shí)候,是非常值得看看這兩個(gè)主要流行的 Python 版本之間的差別的,以便避免常見的陷阱。
future模塊
Python 3.x 介紹的 一些Python 2 不兼容的關(guān)鍵字和特性可以通過在 Python 2 的內(nèi)置__future__模塊導(dǎo)入。如果你計(jì)劃讓你的代碼支持 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ù)取代了,這意味著我們必須包裝我們想打印在小括號(hào)中的對(duì)象。
Python 2 不具有額外的小括號(hào)問題。但對(duì)比一下,如果我們按照 Python 2 的方式不使用小括號(hào)調(diào)用print函數(shù),Python 3 將拋出一個(gè)語法異常(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"是非常正常的,盡管如此,如果你有多個(gè)對(duì)象在小括號(hào)中,我們將創(chuàng)建一個(gè)元組,因?yàn)閜rint在 Python 2 中是一個(gè)聲明,而不是一個(gè)函數(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)建迭代對(duì)象的用法是非常流行的。比如: for 循環(huán)或者是列表/集合/字典推導(dǎo)式。
這個(gè)表現(xiàn)十分像生成器(比如?!岸栊郧笾怠?。但是這個(gè)xrange-iterable是無窮的,意味著你可以無限遍歷。
由于它的惰性求值,如果你不得僅僅不遍歷它一次,xrange()函數(shù) 比range()更快(比如 for 循環(huán))。盡管如此,對(duì)比迭代一次,不建議你重復(fù)迭代多次,因?yàn)樯善髅看味紡念^開始。
在 Python 3 中,range()是像xrange()那樣實(shí)現(xiàn)以至于一個(gè)專門的xrange()函數(shù)都不再存在(在 Python 3 中xrange()會(huì)拋出命名異常)。
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對(duì)象的__contains__方法
另外一件值得一提的事情就是在 Python 3 中range有一個(gè)新的__contains__方法(感謝Yuchen Ying指出了這個(gè)),__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)它使一個(gè)整數(shù)類型,而不是浮點(diǎn)類型的時(shí)候,你可以看到執(zhí)行查找的速度是 60000 倍快。盡管如此,因?yàn)?Python 2.x 的range或者是xrange沒有一個(gè)__contains__方法,這個(gè)整數(shù)類型或者是浮點(diǎn)類型的查詢速度不會(huì)相差太大。
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()之間的速度不同。因?yàn)樗麄兪怯孟嗤姆椒▽?shí)現(xiàn)的,因此期望相同的速度。盡管如此,這事實(shí)在于 Python 3 傾向于比 Python 2 運(yùn)行的慢一點(diǎn)。
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