摘要:跳轉到章節預覽在中創建迭代對象的用法是非常流行的。循環變量和全局命名空間泄漏好消息在中循環變量不會再導致命名空間泄漏。通過解析用戶的輸入幸運的是,在中已經解決了把用戶的輸入存儲為一個對象的問題。
注:本文的原文地址為
Key differences between Python 2.7.x and Python 3.x
許多 Python 初學者想知道他們應該從 Python 的哪個版本開始學習。對于這個問題我的答案是 “你學習你喜歡的教程的版本,然后檢查他們之間的不同。"
但是如果你開始一個新項目,并且有選擇權?我想說的是目前沒有對錯,只要你計劃使用的庫 Python 2.7.x 和 Python 3.x 雙方都支持的話。盡管如此,當在編寫它們中的任何一個的代碼,或者是你計劃移植你的項目的時候,是非常值得看看這兩個主要流行的 Python 版本之間的差別的,以便避免常見的陷阱,
章節使用 __future__ 模塊
print 函數
Integer division
Unicode
xrange
Raising exceptions
Handling exceptions
next() 函數 和 .next() 方法
For 循環變量和全局命名空間泄漏
比較不可排序類型
通過 input() 解析用戶的輸入
返回可迭代對象,而不是列表
更多的關于 Python 2 和 Python 3 的文章
future 模塊Python 3.x 介紹的 一些Python 2 不兼容的關鍵字和特性可以通過在 Python 2 的內置 __future__ 模塊導入。如果你計劃讓你的代碼支持 Python 3.x,建議你使用 __future__ 模塊導入。例如,如果我想要 在Python 2 中表現 Python 3.x 中的整除,我們可以通過如下導入
from __future__ import division
更多的 __future__ 模塊可被導入的特性被列在下表中:
feature | optional in | mandatory in | effect |
---|---|---|---|
nested_scopes | 2.1.0b1 | 2.2 | PEP 227: Statically Nested Scopes |
generators | 2.2.0a1 | 2.3 | PEP 255: Simple Generators |
division | 2.2.0a2 | 3.0 | PEP 238: Changing the Division Operator |
absolute_import | 2.5.0a1 | 3.0 | PEP 328: Imports: Multi-Line and Absolute/Relative |
with_statement | 2.5.0a1 | 2.6 | PEP 343: The “with” Statement |
print_function | 2.6.0a2 | 3.0 | PEP 3105: Make print a function |
unicode_literals | 2.6.0a2 | 3.0 | PEP 3112: Bytes literals in Python 3000 |
(Source: https://docs.python.org/2/library/future.html)
from platform import python_versionprint 函數
[跳轉到章節預覽]
很瑣碎,而 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"
Python 2.7.6 Hello, World! Hello, World! text print more text on the same line
Python 3
print("Python", python_version()) print("Hello, World!") print("some text,", end="") print(" print more text on the same line")
Python 3.4.1 Hello, World! some text, print more text on the same line
print "Hello, World!"
File "", line 1 print "Hello, World!" ^ SyntaxError: invalid syntax
注意
以上通過 Python 2 使用 Printing "Hello, World" 是非常正常的,盡管如此,如果你有多個對象在小括號中,我們將創建一個元組,因為 print 在 Python 2 中是一個聲明,而不是一個函數調用。
print "Python", python_version() print("a", "b") print "a", "b"
Python 2.7.7 ("a", "b") a b整除
[跳轉到章節預覽]
如果你正在移植代碼,這個變化是特別危險的。或者你在 Python 2 上執行 Python 3 的代碼。因為這個整除的變化表現在它會被忽視(即它不會拋出語法異常)。
因此,我還是傾向于使用一個 float(3)/2 或 3/2.0 代替在我的 Python 3 腳本保存在 Python 2 中的 3/2 的一些麻煩(并且反而過來也一樣,我建議在你的 Python 2 腳本中使用 from __future__ import division)
Python 2
print "Python", python_version() print "3 / 2 =", 3 / 2 print "3 // 2 =", 3 // 2 print "3 / 2.0 =", 3 / 2.0 print "3 // 2.0 =", 3 // 2.0
Python 2.7.6 3 / 2 = 1 3 // 2 = 1 3 / 2.0 = 1.5 3 // 2.0 = 1.0
Python 3
print("Python", python_version()) print("3 / 2 =", 3 / 2) print("3 // 2 =", 3 // 2) print("3 / 2.0 =", 3 / 2.0) print("3 // 2.0 =", 3 // 2.0)
Unicode
Python 3.4.1 3 / 2 = 1.5 3 // 2 = 1 3 / 2.0 = 1.5 3 // 2.0 = 1.0
[跳轉到章節預覽]
Python 2 有 ASCII str() 類型,unicode() 是多帶帶的,不是 byte 類型。
現在, 在 Python 3,我們最終有了 Unicode (utf-8) 字符串,以及一個字節類:byte 和 bytearrays。
Python 2
print "Python", python_version()
Python 2.7.6
print type(unicode("this is like a python3 str type"))
print type(b"byte type does not exist")
print "they are really" + b" the same" they are really the same
print type(bytearray(b"bytearray oddly does exist though"))
Python 3
print("Python", python_version()) print("strings are now utf-8 u03BCnicou0394é!") Python 3.4.1 strings are now utf-8 μnicoΔé!
print("Python", python_version(), end="") print(" has", type(b" bytes for storing data")) Python 3.4.1 has
print("and Python", python_version(), end="") print(" also has", type(bytearray(b"bytearrays"))) and Python 3.4.1 also has
"note that we cannot add a string" + b"bytes for data" --------------------------------------------------------------------------- TypeError Traceback (most recent call last)xrangein () ----> 1 "note that we cannot add a string" + b"bytes for data" TypeError: Can"t convert "bytes" object to str implicitly
[跳轉到章節預覽]
在 Python 2 中 xrange() 創建迭代對象的用法是非常流行的。比如: for 循環或者是列表/集合/字典推導式。
這個表現十分像生成器(比如。“惰性求值”)。但是這個 xrange-iterable 是無窮的,意味著你可以無限遍歷。
由于它的惰性求值,如果你不得僅僅不遍歷它一次,xrange() 函數 比 range() 更快(比如 for 循環)。盡管如此,對比迭代一次,不建議你重復迭代多次,因為生成器每次都從頭開始。
在 Python 3 中,range() 是像 xrange() 那樣實現以至于一個專門的 xrange() 函數都不再存在(在 Python 3 中 xrange() 會拋出命名異常)。
import timeit n = 10000 def test_range(n): return for i in range(n): pass def test_xrange(n): for i in xrange(n): pass
Python 2
print "Python", python_version() print " timing range()" %timeit test_range(n) print " timing xrange()" %timeit test_xrange(n) Python 2.7.6 timing range() 1000 loops, best of 3: 433 μs per loop timing xrange() 1000 loops, best of 3: 350 μs per loop
Python 3
print("Python", python_version()) print(" timing range()") %timeit test_range(n) Python 3.4.1 timing range() 1000 loops, best of 3: 520 μs per loop
print(xrange(10)) --------------------------------------------------------------------------- NameError Traceback (most recent call last)in () ----> 1 print(xrange(10)) NameError: name "xrange" is not defined
Python 3 中的 range 對象的 __contains__ 方法
另外一件值得一提的事情就是在 Python 3 中 range 有一個新的 __contains__ 方法(感謝 Yuchen Ying 指出了這個),__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 的結果,當它使一個整數類型,而不是浮點類型的時候,你可以看到執行查找的速度是 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) 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
下面說下 __contain__ 方法并沒有加入到 Python 2.x 中的證據:
print("Python", python_version()) range.__contains__ Python 3.4.1
print "Python", python_version() range.__contains__ Python 2.7.7 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last)in () 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 和 Python 3 中速度的不同***
有些猿類指出了 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 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 loopRaising exceptions
[跳轉到章節預覽]
Python 2 接受新舊兩種語法標記,在 Python 3 中如果我不用小括號把異常參數括起來就會阻塞(并且反過來引發一個語法異常)。
Python 2
print "Python", python_version() Python 2.7.6
raise IOError, "file error" --------------------------------------------------------------------------- IOError Traceback (most recent call last)in () ----> 1 raise IOError, "file error" IOError: file error
raise IOError("file error") --------------------------------------------------------------------------- IOError Traceback (most recent call last)in () ----> 1 raise IOError("file error") IOError: file error
Python 3
print("Python", python_version()) Python 3.4.1
raise IOError, "file error"
File "", line 1 raise IOError, "file error" ^ SyntaxError: invalid syntax The proper way to raise an exception in Python 3:
Handling exceptions
print("Python", python_version()) raise IOError("file error") Python 3.4.1 --------------------------------------------------------------------------- OSError Traceback (most recent call last)in () 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 messagenext() 函數 and .next() 方法
因為 next() (.next()) 是一個如此普通的使用函數(方法),這里有另外一個語法改變(或者是實現上改變了),值得一提的是:在 Python 2.7.5 中函數和方法你都可以使用,next() 函數在 Python 3 中一直保留著(調用 .next() 拋出屬性異常)。
Python 2
print "Python", python_version() my_generator = (letter for letter in "abcdefg") next(my_generator) my_generator.next()
Python 2.7.6 "b"
Python 3
print("Python", python_version()) my_generator = (letter for letter in "abcdefg") next(my_generator)
Python 3.4.1 "a"
my_generator.next()
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last)For 循環變量和全局命名空間泄漏in () ----> 1 my_generator.next() AttributeError: "generator" object has no attribute "next"
好消息:在 Python 3.x 中 for 循環變量不會再導致命名空間泄漏。
在 Python 3.x 中做了一個改變,在 What’s New In Python 3.0 中有如下描述:
"列表推導不再支持 [... for var in item1, item2, ...] 這樣的語法。使用 [... for var in (item1, item2, ...)] 代替。也需要提醒的是列表推導有不同的語義: 他們關閉了在 `list()` 構造器中的生成器表達式的語法糖, 并且特別是循環控制變量不再泄漏進周圍的作用范圍域."
Python 2
print "Python", python_version() i = 1 print "before: i =", i print "comprehension: ", [i for i in range(5)] print "after: i =", i Python 2.7.6 before: i = 1 comprehension: [0, 1, 2, 3, 4] after: i = 4
Python 3
print("Python", python_version()) i = 1 print("before: i =", i) print("comprehension:", [i for i in range(5)]) print("after: i =", i) Python 3.4.1 before: i = 1 comprehension: [0, 1, 2, 3, 4] after: i = 1比較不可排序類型
在 Python 3 中的另外一個變化就是當對不可排序類型做比較的時候,會拋出一個類型錯誤。
Python 2
print "Python", python_version() print "[1, 2] > "foo" = ", [1, 2] > "foo" print "(1, 2) > "foo" = ", (1, 2) > "foo" print "[1, 2] > (1, 2) = ", [1, 2] > (1, 2) Python 2.7.6 [1, 2] > "foo" = False (1, 2) > "foo" = True [1, 2] > (1, 2) = False
Python 3
print("Python", python_version()) print("[1, 2] > "foo" = ", [1, 2] > "foo") print("(1, 2) > "foo" = ", (1, 2) > "foo") print("[1, 2] > (1, 2) = ", [1, 2] > (1, 2)) Python 3.4.1 --------------------------------------------------------------------------- TypeError Traceback (most recent call last)通過 input() 解析用戶的輸入in () 1 print("Python", python_version()) ----> 2 print("[1, 2] > "foo" = ", [1, 2] > "foo") 3 print("(1, 2) > "foo" = ", (1, 2) > "foo") 4 print("[1, 2] > (1, 2) = ", [1, 2] > (1, 2)) TypeError: unorderable types: list() > str()
幸運的是,在 Python 3 中已經解決了把用戶的輸入存儲為一個 str 對象的問題。為了避免在 Python 2 中的讀取非字符串類型的危險行為,我們不得不使用 raw_input() 代替。
Python 2
Python 2.7.6 [GCC 4.0.1 (Apple Inc. build 5493)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> my_input = input("enter a number: ") enter a number: 123 >>> type(my_input)>>> my_input = raw_input("enter a number: ") enter a number: 123 >>> type(my_input)
Python 3
Python 3.4.1 [GCC 4.2.1 (Apple Inc. build 5577)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> my_input = input("enter a number: ") enter a number: 123 >>> type(my_input)返回可迭代對象,而不是列表
如果在 xrange 章節看到的,現在在 Python 3 中一些方法和函數返回迭代對象 -- 代替 Python 2 中的列表
因為我們通常那些遍歷只有一次,我認為這個改變對節約內存很有意義。盡管如此,它也是可能的,相對于生成器 --- 如需要遍歷多次。它是不那么高效的。
而對于那些情況下,我們真正需要的是列表對象,我們可以通過 list() 函數簡單的把迭代對象轉換成一個列表。
Python 2
print "Python", python_version() print range(3) print type(range(3)) Python 2.7.6 [0, 1, 2]
Python 3
print("Python", python_version()) print(range(3)) print(type(range(3))) print(list(range(3))) Python 3.4.1 range(0, 3)[0, 1, 2]
在 Python 3 中一些經常使用到的不再返回列表的函數和方法:
zip()
map()
filter()
dictionary"s .keys() method
dictionary"s .values() method
dictionary"s .items() method
更多的關于 Python 2 和 Python 3 的文章下面是我建議后續的關于 Python 2 和 Python 3 的一些好文章。
移植到 Python 3
Should I use Python 2 or Python 3 for my development activity?
What’s New In Python 3.0
Porting to Python 3
Porting Python 2 Code to Python 3
How keep Python 3 moving forward
Python 3 的擁護者和反對者
10 awesome features of Python that you can"t use because you refuse to upgrade to Python 3
Everything you did not want to know about Unicode in Python 3
Python 3 is killing Python
Python 3 can revive Python
Python 3 is fine
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/37325.html
摘要:你使用的系統自帶的包管理器包索引也被稱為各種源碼托管服務,如,,等。通過系統自帶的包管理器安裝使用系統自帶的包管理器安裝,只需要在命令行輸入相應命令,或是使用你用來安裝其他應用的應用即可。 譯者按:原文寫于2011年末,雖然文中關于Python 3的一些說法可以說已經不成立了,但是作為一篇面向從其他語言轉型到Python的程序員來說,本文對Python的生態系統還是做了較為全面的介紹...
摘要:與的區別默認編碼方式是碼。中輸入內容分為和兩個函數,前者只接受文本輸入,而在中只有且統一將用戶的輸入存儲為對象。中不再使用和后綴說明長整型。 python2與python3的區別python2默認編碼方式是ascii碼。(可在文件的首行:# -*- encoding:utf-8 -*...
摘要:官方也宣布在停止對的維護。并且在很多面試過程中,面試官都會問與的區別。的版本,常被稱為,或簡稱。與部分地支持這種形式的語法。捕獲異常的語法由改為。在中,表示八進制字面量的方式只有一種,就是。已經支援新的模組。 前言 如果你是剛接觸 Python 的初學者,那你可能是直接學習 Python 3.x 版本。對于 Python 2.x 的版本是不會有所接觸。官方也宣布在 2020 停止對 P...
摘要:用于下載網頁內容,并將網頁內容返回給。中間件位于引擎和下載器之間的鉤子框架,主要是處理引擎與下載器之間的請求及響應。包含了在啟動時進行爬取的列表。對象經過調度,執行生成對象并送回給方法一般返回實例。 Scrapy 是什么 Scrapy 是一個為了爬取網站數據,提取結構性數據而編寫的應用框架。 可以應用在包括數據挖掘,信息處理或存儲歷史數據等一系列的程序中。其最初是為了頁面抓取 (更確切...
摘要:認為有極大的優化空間,在字符串和整形操作上可以取得很好的優化結果。的和方法返回迭代器,而之前的等函數都被廢棄。python有兩個主要的版本,python2 和 python3 ,但是python又不同于其他語言,向下兼容,python3是不向下兼容的,但是絕大多數組件和擴展都是基于python2的,下面就來總結一下python2和python3的區別。 ? 1.性能? Py3.0運...
閱讀 4009·2023-04-26 02:13
閱讀 2252·2021-11-08 13:13
閱讀 2740·2021-10-11 10:59
閱讀 1740·2021-09-03 00:23
閱讀 1311·2019-08-30 15:53
閱讀 2287·2019-08-28 18:22
閱讀 3059·2019-08-26 10:45
閱讀 737·2019-08-23 17:58