1. 程式人生 > >13條Python2.x和3.x的區別?

13條Python2.x和3.x的區別?

關鍵詞 去除 網絡 開篇 UNC 接收 var future await

從今天開始,小明將和你一起過一下,那些在面試「Python開發」崗位時面試官喜歡問的問題。內容基礎,但是你不一定會噢。

這些問題全部來自個人經驗,群友推薦以及網絡上的帖子。如果你有好的問題,也可以隨時向我提出(不要覺得簡單),我會篩選後整理出來在這裏,供大家學習取經,給大家在求職路上貢獻一份力。

開篇講些什麽好呢?

今天就來羅列一下,Python2.x和3.x到底有哪些區別吧。

去×××

你隨便全使用搜索引擎都可以查到這些資料,但是大家說的都是一些普遍都知道的事兒。或者都是抄來抄去,內容相差無幾。

授人以魚,不如授人以漁。

在列舉之前,我要先教下大家,如何找到那沒有經人加工過的第一手資料。

那當然是官網啦:https://www.python.org/downloads/

這個地址裏,有所有Python歷史版本(2.0+)。
點擊左邊,Release Version欄目 對應的版本。
技術分享圖片

進入對應詳情頁後,找到如圖 what‘s new in Python xx 就可以查看此版本的新特性。
技術分享圖片

網頁是全英文的,需要你有一定的英文閱讀能力。快去感覺一下吧。

接下來。和大家一起過一下,Python2.x和3.x到底有哪些區別,這不僅在你開發過程中需要考慮的,也是面試過程面試官經常會問及的。

1. print

在Python 2.6之前,只支持

print "hello"

在Python 2.6和2.7中,可以支持如下三種

print "hello"
print("hello")
print ("hello")

在Python3.x中,可以支持如下兩種

print("hello")
print ("hello")

2. 編碼方式

在Python2.x中,默認使用ASCII編碼。

所以默認情況下,我們不能在程序中使用中文。若要使用中文,必須在文件頭部,聲明使用 "UTF-8" 編碼,並在使用的時候註意編碼轉換,要打印的時候需先轉成"Unicode"編碼,否則會亂碼。

Python 2的正確使用方法,如下

# coding:utf-8

str1="中國"
print str1.decode("utf-8")

亦或者可以這樣,u表示,這個字符串使用Unicode編碼,不再需要轉換。

# coding:utf-8

str1=u"中國"
print str1

在Python3.x中,默認使用Unicode的UTF-8編碼。

所以我們可以在程序中,隨意的使用中文(但並不推薦),不會報錯。

3. 除法運算

Python 2.x中除法運算,整數間運算只保留整數(向下取整)。

>>> 8/2
4
>>> 8/3
2
>>> -8/3
-3
>>> -8/3.0
-2.6666666666666665

Python 3.x中除法運算,全部保留小數(即使能被整除)。

>>> 8/2
4.0
>>> 8/3
2.6666666666666665

這裏要說明一下,3.x 中的//用法和 2.x 用法是一樣的。這個運算叫做 floor 運算,即向下取整。

>>> 8//2   
4          
>>> 8//3   
2
>>> -8//3.0
-3.0

4. 異常捕獲

在 Python 3 中,只能使用 as 作為關鍵詞。而在Python 2中經常使用 except Exception, e
使用語法except (exc1, exc2) as var可以同時捕獲多種類別的異常。

Python 2.6已經支持這兩種語法。

  • 在2.x時代,所有類型的對象都是可以被直接拋出的,在3.x時代,只有繼承自BaseException的對象才可以被拋出。
  • 2.x raise語句使用逗號將拋出對象類型和參數分開,3.x取消了這種奇葩的寫法,直接調用構造函數拋出對象即可。

在2.x時代,異常在代碼中除了表示程序錯誤,還經常做一些普通控制結構應該做的事情,在3.x中可以看出,設計者讓異常變的更加專一,只有在錯誤發生的情況才能去用異常捕獲語句來處理。

5. xrange

首先,要了解的是,xrange是只有在Python2.x中才有的產物。

在 2.x 中xrange和range的使用方法可以說完全一致。只是從內部來看,range是返回一個list對象,而xrange返回一個生成器對象,所以在處理大批量數據時,xrange的性能會更好。

>>>xrange(1,5)
xrange(1, 5)

>>>list(xrange(1,5))
[1, 2, 3, 4]

而在3.x 中,只有range函數,為什麽沒有xrange,因為3.x中的range其實就是2.x中的xrange。你可以這樣理解。

>>> range(10)
range(0, 10)

6. 用戶輸入

在2.x 中,有兩個函數。raw_input()和input()。

  • raw_input():將所有輸入作為字符串看待,返回字符串類型。
  • input():只能接收"數字"的輸入。

在3.x 中,對這兩個函數進行整合,只留下一個input(),既可輸入數字,也可輸入字符串,返回的是字符串類型。

7. 數據類型

Python 3.x 一個很重要的特性是,對字符串和二進制數據流做了明確的區分。

文本總是Unicode,由str類型表示,二進制數據則由bytes類型表示。

Python 3不會以任意隱式的方式混用str和bytes,你不能拼接字符串和字節流,也無法在字節流裏搜索字符串(反之亦然),也不能將字符串傳入參數為字節流的函數(反之亦然)。

更為詳細的剖析,可以前往:https://www.cnblogs.com/chownjy/p/6625299.html

還有一點是,3.X去除了long類型,取代它的是整型(int)。3.x的整型是沒有限制大小的,可以當做long類型使用, 但實際上由於機器內存的有限,我們使用的整數是不可能無限大的。

8. 函數式編程

在Python中,我們常常使用到的map,filter,reduce,在2.x和3.x中也有所不同。

在2.x中,這三貨,是內建函數。返回的是一個列表。


>>> map
<built-in function map>

>>> filter
<built-in function filter>

>>> map(lambda x:x *2, [1,2,3])
[2, 4, 6]

>>> filter(lambda x:x %2 ==0,range(10))
[0, 2, 4, 6, 8]

在3.x中,前面兩貨,卻變成類了。返回的是可叠代對象。

>>> map
<class ‘map‘>

>>> map(print,[1,2,3])
<map object at 0x10d8bd400>

>>> filter
<class ‘filter‘>

>>> filter(lambda x:x % 2 == 0, range(10))
<filter object at 0x10d8bd3c8>

對於 reduce 函數,它在 Python 3.x 中已經不屬於 built-in 了,被挪到 functools 模塊當中。

9. 協程關鍵字

在Python3.3後,協程中,新增了yield from 和 async/await 關鍵字,這在2.x中是沒有。

關於yield from的語法剖析,可以前往查看我的另一篇文章。

10. 類的類型

Python2.x 默認使用經典類,只有顯示繼承object才是新式類。

Python3.x 沒有經典類,只有新式類,而且有三種寫法

class Cls:
    pass

class Cls():
    pass

class Cls(object):
    pass

11. 變量作用域

  • 在2.x中無法將局部變量聲明為全局變量。
  • 在3.x中可以使用nonlocal語法將局部變量聲明為全局變量。
def foo():
    var=100
    def bar():
        nonlocal var
        var=200
    bar()
    print(var)
foo()

# 2.x輸出:100
# 3.x輸出:200

12. 元類的使用

在2.x 中

class Metaclass(type):
    pass

class Person(list):
    __metaclass__ = Metaclass 
    pass

在3.x中

class MetaPerson(type):
    pass

class Person(metaclass=MetaPerson):
    pass

13. 模塊變化

  • 去掉了一些模塊。由於不常用,這裏就不列舉了。
  • 新增了一些模塊。比如:concurrent.futures,asyncio等
  • 修改了一些模塊。比如:Queue改成queue。

大概就是這些內容,可能還有更細微的差別,這些內容要前往官網查看。但是那些對於我們普通開發者來說,並不那麽重要。完全可以不去關註。

實際上,當我熟悉一個版本後,基本上是可以無縫過渡到另一個版本的。這篇文章,更多的是為了科普和應對面試。

13條Python2.x和3.x的區別?