當前位置:
首頁 > 最新 > Python 2與Python 3 的區別

Python 2與Python 3 的區別

信息安全公益宣傳,信息安全知識啟蒙。

教程列表見微信公眾號底部菜單

越來越多的庫要放棄Python 2了,開始轉向Python 3了。最近的項目開始用Python3寫了,也體會了一下2和3的區別。主要的一些區別在以下幾個方面:

print函數

整數相除

Unicode

異常處理

xrange

map函數

不支持has_key


Python 2中print是語句(statement),Python 3中print則變成了函數。在Python 3中調用print需要加上括弧,不加括弧會報SyntaxError

Python 2

print"hello world"

輸出

hello world

Python 3

print("hello world")

輸出

hello world

print"hello world"

輸出

File"", line1

print"hello world"

^

SyntaxError: Missing parenthesesincall to"print"


在Python 2中,3/2的結果是整數,在Python 3中,結果則是浮點數

Python 2

print"3 / 2 =",3/2

print"3 / 2.0 =",3/2.0

輸出

3/2=1

3/2.0=1.5

Python 3

print("3 / 2 =",3/2)

print("3 / 2.0 =",3/2.0)

輸出

3/2=1.5

3/2.0=1.5


Python 2有兩種字元串類型:str和unicode,Python 3中的字元串默認就是Unicode,Python 3中的str相當於Python 2中的unicode。

在Python 2中,如果代碼中包含非英文字元,需要在代碼文件的最開始聲明編碼,如下:

# -*- coding: utf-8 -*-

在Python 3中,默認的字元串就是Unicode,就省去了這個麻煩,下面的代碼在Python 3可以正常地運行。

a ="你好"

print(a)

Python 2中捕獲異常一般用下面的語法

try:

1/

exceptZeroDivisionError, e:

printstr(e)

或者

try:

1/

exceptZeroDivisionErrorase:

printstr(e)

Python 3中不再支持前一種語法,必須使用as關鍵字。


Python 2中有 range 和 xrange 兩個方法。其區別在於,range返回一個list,在被調用的時候即返回整個序列;xrange返回一個iterator,在每次循環中生成序列的下一個數字。Python 3中不再支持 xrange 方法,Python 3中的 range 方法就相當於 Python 2中的 xrange 方法。


在Python 2中,map函數返回list,而在Python 3中,map函數返回iterator。

Python 2

map(lambdax: x+1, range(5))

輸出

[1,2,3,4,5]

Python 3

map(lambdax: x+1, range(5))

輸出

list(map(lambdax: x+1, range(5)))

輸出

[1,2,3,4,5]

filter函數在Python 2和Python 3中也是同樣的區別。


Python 3中的字典不再支持has_key方法

Python 2

person = {"age":30,"name":"Xiao Wang"}

print"person has key "age": ", person.has_key("age")

print"person has key "age": ","age"inperson

輸出

person has key"age":True

person has key"age":True

Python 3

person = {"age":30,"name":"Xiao Wang"}

print("person has key "age": ","age"inperson)

輸出

person has key"age":True

print("person has key "age": ", person.has_key("age"))

輸出

Traceback (most recent call last):

File"", line1,in

AttributeError:"dict"object has no attribute"has_key"

print函數

在py2中print是一個語法結構,而在py3中print是一個函數,

print(value, ..., sep=" ", end="
",file=sys.stdout, flush=False)

file可以是文件,也就是可以把列印的東西直接輸出到文件,這個就很方便,我經常用。比如:

a = range(10)

out_file = open(「print_test_file.txt」, 『w』)

for x in a:

print(x,sep=』 『, end = 「
」, file=out_file)

編碼問題

在py2中,編碼問題是個大問題,可以單獨拉出來講一次。這裡簡單說一下,在py2中,把字元串分為Unicode和str兩種類型。

>>> s1 = "machine learning"

>>> type(s1)

>>> s2 = u"machine learning"

>>> type(s2)

>>> s3 = "中國"

>>> type(s3)

"xd6xd0xb9xfa"

>>> s4 = u"中國"

>>> type(s4)

py3中沒有Unicode,他們都是字元串

>>> s1 = "machine learning"

>>> type(s1)

>>> s2 = u"machine learning"

>>> type(s2)

>>> s3 = "中國"

>>> type(s3)

"中國"

當我們需要把py2中的unicode字元輸出到文件或者傳輸到網路上,需要先把unicode字元轉換為str類型,py2的encode方法就是編碼unicode字元到指定字元類型,因為py2默認編碼方式為unicode,所以當使用encode方式時,傳入的參數就是目標編碼格式,比如utf-8或者gbk等,當py2把一個字元存入到文件的時候,首先會判斷字元的類型,如果是str,則直接存入文件,如果是Unicode類型,則先要轉換為str類型,就需要encode方法,這時候默認的是ascii字元,然後ascii字元是不包括中文的,所以會引發UnicodeEncodeError。而decode是把str轉換為unicode字元,剛說了py2的默認格式是unicode,所以decode的時候,需要傳入的參數名字就是字元的現在的編碼的編碼方式,比如utf-8或者gbk,當傳入的參數名字不是現在編碼方式的時候,就會引發UnicodeDecodeError。

好了,這是py2中的坑,這些問題在py3中統統得到了解決。py3中沒有Unicode和str的區別,Unicode字元也會當做utf-8來看待,我們知道utf-8是包括中文的,所以當把中文字元存入文件的時候,就不會發生編碼問題。這也是為什麼當代碼中包括中文的時候,不需要在第一行顯式的指定編碼格式,# coding:utf-8.

除法問題

在py2中兩個整數除法的得到的是0,要得到浮點數,則除數或者被除數有一個是浮點數,而在py3中,整數相除可以得到浮點數。但是如果要在py3中整數相除也得到0的話,就要使用//,而不是/。

# python2

print 1/2

print 1/2.

# python3

print(1/2)

print(1//2)

nonlocal 語句

py3 新加入的,可以指定非全局變數。

輸入函數

在py2中輸入函數是raw_input和input兩個函數, 而py3中刪除了raw_inpus, 只使用input

I/O方法,xreadlines()

在py2中,一個文件對象有xreadlines()方法,返回一個迭代器,每次只讀取一行數據,可以使用for循環輸出結果。在py3中刪除了這個方法。

cPickle

py2中的cPickle被移除,py3中被pickle代替。

urllib

py2中存在兩個包,urllib和urllib2,是爬蟲經常用的模塊,py3中統一到了urllib中。並且py2中的urlparse模塊被統一到了urllib.parse模塊下。

包內的相對導入

這個挺重要的一個改變,需要掌握一下。在py2中,假設你寫了三個.py的模塊,比如:

--first.py

--second.py

--third.py

你想在3.py中導入1和2,可以直接

import first

import second

因為py2的解釋器會首先在當前目錄下搜索first和second,沒有找到才會去python的路徑中去找。而在py3中就不行,你需要這樣做

from . import first

from . import second

因為py3會直接在python 的路徑中去搜索,如果first.py和second.py在父目錄當中,則需要這樣

from .. import first

from .. import second

多加一個點,就這樣,是不是很簡單。

新式的8進位變數,修改了oct函數,oct是返回一個整形或者長整形的8進位數。

py2可以這樣

438

>>> oct(438)

『0666』

在py3中

SyntaxError: invalid token

438

>>> oct(438)

『0o666』

新的super方法,可以不傳參數

>>> class A(object):

def__init__(self, a):

print("A",a)

>>> class B(A):

def__init__(self, a):

super().__init__(a)

A 8

dict的.keys(),items(),values()方法返回一個迭代器,iterkeys(),has_key()廢棄。

python3引入抽象基類

Abstract Base Classes, ABCs

迭代器

迭代器的next()方法改名為__next__,增加了內置函數next()

增加裝飾器

@abstractmethod 和@anstractproperty兩個新裝飾器,編寫抽象方法更加方便。

移除了imageop,audiodev, Bastion, bsddb,bsddb185, exceptions,linuxaudiodev, md5, MimeWrite, mimify, popen2, rexec, sets, sha, strinold,strop, sunaudiodev, timing, xmlib, new模塊

這些是自帶的模塊,在py3中還移除了一些第三方模塊。

os模塊中的os.tmpnam()和os.tmpfile()移到tmpfile模塊中

http

在py2中相關的模塊由httplib,Cookie, cookielib, BaseHTTPServer, SimpleHTTPServer, CGIHttpServer,在py3中統一到了http模塊中,變成http.client,http.cookies, http.cookiejar, http.server.

urllib

py2中存在兩個包,urllib和urllib2,是爬蟲經常用的模塊,py3中統一到了urllib中。並且py2中的urlparse模塊被統一到了urllib.parse模塊下。

包內的相對導入

這個挺重要的一個改變,需要掌握一下。在py2中,假設你寫了三個.py的模塊,比如:

--first.py

--second.py

--third.py

你想在3.py中導入1和2,可以直接

import first

import second

因為py2的解釋器會首先在當前目錄下搜索first和second,沒有找到才會去python的路徑中去找。而在py3中就不行,你需要這樣做

from . import first

from . import second

因為py3會直接在python 的路徑中去搜索,如果first.py和second.py在父目錄當中,則需要這樣

from .. import first

from .. import second

多加一個點,就這樣,是不是很簡單。

GIF


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python 的精彩文章:

今晚20:30直播授課教學答題輔助
Python-GUI Tkinter模塊

TAG:Python |