溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python中類(lèi)與類(lèi)型的區(qū)別是什么

發(fā)布時(shí)間:2021-06-04 16:43:00 來(lái)源:億速云 閱讀:382 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

今天就跟大家聊聊有關(guān)Python中類(lèi)與類(lèi)型的區(qū)別是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

1.經(jīng)典類(lèi)與新式類(lèi)

在了解Python的類(lèi)與類(lèi)型前,需要對(duì)Python的經(jīng)典類(lèi)(classic classes)與新式類(lèi)(new-style classes)有個(gè)簡(jiǎn)單的概念。

在Python 2.x及以前的版本中,由任意內(nèi)置類(lèi)型派生出的類(lèi)(只要一個(gè)內(nèi)置類(lèi)型位于類(lèi)樹(shù)的某個(gè)位置),都屬于“新式類(lèi)”,都會(huì)獲得所有“新式類(lèi)”的特性;反之,即不由任意內(nèi)置類(lèi)型派生出的類(lèi),則稱之為“經(jīng)典類(lèi)”。

“新式類(lèi)”和“經(jīng)典類(lèi)”的區(qū)分在Python 3.x之后就已經(jīng)不存在,在Python 3.x之后的版本,因?yàn)樗械念?lèi)都派生自內(nèi)置類(lèi)型object(即使沒(méi)有顯示的繼承object類(lèi)型),即所有的類(lèi)都是“新式類(lèi)”。

2.類(lèi)的實(shí)例與對(duì)象

在很多語(yǔ)言中,類(lèi)的實(shí)例與類(lèi)的對(duì)象,只是同一事物的不同名稱。而在Python中,類(lèi)的對(duì)象與類(lèi)的實(shí)例,是完全不同的概念。在本文中,所稱的類(lèi)對(duì)象,是指由class代碼塊執(zhí)行后創(chuàng)建的類(lèi)對(duì)象,而類(lèi)的實(shí)例則是由類(lèi)對(duì)象所創(chuàng)建的實(shí)例。這里只做簡(jiǎn)單提及,便于下文理解,要更深入的理解這個(gè)概念,可以參考“python一切皆對(duì)象”的相關(guān)知識(shí)。

3.類(lèi)實(shí)例的類(lèi)與類(lèi)型

嘗試分別在Python 2.x 和 3.x 版本中運(yùn)行如下代碼:

class A():pass
class B():pass

a = A()
b = B()

if __name__ == '__main__':
  print(type(a))
  print(type(b))
  print(type(a) == type(b))
  print(a.__class__)
  print(b.__class__)
  print(a.__class__ == b.__class__)

Python 2.6.9 及 2.7.10 的運(yùn)行結(jié)果:

Python中類(lèi)與類(lèi)型的區(qū)別是什么

在Python 2.x及以前的版本,所有經(jīng)典類(lèi)的實(shí)例都是“instance”(實(shí)例類(lèi)型)。所以比較經(jīng)典類(lèi)實(shí)例的類(lèi)型(type)毫無(wú)意義,因?yàn)樗械慕?jīng)典類(lèi)實(shí)例都是instance類(lèi)型,比較的結(jié)果通常為T(mén)rue。更多情況下需要比較經(jīng)典類(lèi)實(shí)例的__class__屬性來(lái)獲得我們想要的結(jié)果(或使用isinstance函數(shù))。

Python 3.5.1 運(yùn)行結(jié)果

Python中類(lèi)與類(lèi)型的區(qū)別是什么

在Python 3.x及之后的版本,類(lèi)和類(lèi)型已經(jīng)合并。類(lèi)實(shí)例的類(lèi)型是這個(gè)實(shí)例所創(chuàng)建自的類(lèi)(通常是和類(lèi)實(shí)例的__class__相同),而不再是Python 2.x版本中的“instance”實(shí)例類(lèi)型。

需要注意的是,在Python 2.x版本中,“經(jīng)典類(lèi)的實(shí)例都是instance類(lèi)型”,這個(gè)結(jié)論只適用于經(jīng)典類(lèi)。對(duì)新式類(lèi)和內(nèi)置類(lèi)型的實(shí)例,它們的類(lèi)型要更加明確。

修改之前的代碼驗(yàn)證上述觀點(diǎn),嘗試讓class a 和 class b 顯示繼承自object,成為“新式類(lèi)”。

class A(object):pass
class B(object):pass

a = A()
b = B()

if __name__ == '__main__':
  print(type(a))
  print(type(b))
  print(type(a) == type(b))
  print(a.__class__)
  print(b.__class__)
  print(a.__class__ == b.__class__)

Python 2.7.10 運(yùn)行結(jié)果:

Python中類(lèi)與類(lèi)型的區(qū)別是什么

代碼運(yùn)行結(jié)果和Python 3.x是完全相同的,可以看出Python 2.x 新式類(lèi)實(shí)例的類(lèi)型就是這個(gè)實(shí)例所創(chuàng)建自的類(lèi)。同時(shí)進(jìn)一步印證在Python 3.x中所有的類(lèi)都是新式類(lèi)(顯示或隱式繼承自object類(lèi))。

接著對(duì)內(nèi)置類(lèi)型進(jìn)行驗(yàn)證,嘗試運(yùn)行以下代碼

print(type([1, 2, 3]))

Python 2.7.10運(yùn)行結(jié)果:

Python中類(lèi)與類(lèi)型的區(qū)別是什么

可以看出,內(nèi)置類(lèi)型實(shí)例的類(lèi)型,也是同新式類(lèi)一樣,是這個(gè)實(shí)例所創(chuàng)建自的類(lèi)。在示例代碼中,我們創(chuàng)建了一個(gè)list,所以實(shí)例的類(lèi)型為list類(lèi)型。

4.類(lèi)的類(lèi)型

如果說(shuō),一個(gè)類(lèi)實(shí)例的類(lèi)型是創(chuàng)建它的類(lèi)(python 3.x),那一個(gè)類(lèi)的類(lèi)型又是什么???

繼續(xù)使用代碼嘗試驗(yàn)證:

class A():pass
class B():pass

if __name__ == '__main__':
  print(type(A))
  print(type(B))
  print(type(A) == type(B))

Python 2.7.10 運(yùn)行結(jié)果:

Python中類(lèi)與類(lèi)型的區(qū)別是什么

從運(yùn)行結(jié)果我們可以看出,在Python 2.x 中,經(jīng)典類(lèi)的類(lèi)型都是classobj。type(A) == type(B)結(jié)果為T(mén)rue,說(shuō)明它們是同一種類(lèi)型。

Python 3.5.1運(yùn)行結(jié)果:

Python中類(lèi)與類(lèi)型的區(qū)別是什么

從運(yùn)行結(jié)果我們可以看出,所有的類(lèi)型都是type類(lèi),再次印證在Python 3.x 類(lèi)與類(lèi)型已經(jīng)完全合并,類(lèi)即類(lèi)型,類(lèi)型即類(lèi)。

再次修改代碼,使 class A 和 B 顯式繼承自 object,成為新式類(lèi),再在Python 2.7.10 下運(yùn)行查看結(jié)果:

Python中類(lèi)與類(lèi)型的區(qū)別是什么

運(yùn)行結(jié)果顯而易見(jiàn),和Python 3.x 是一樣的,因?yàn)樗鼈兌际切率筋?lèi)。

注:在運(yùn)行結(jié)果中,Python 2.x 顯示為 <type 'type'>,而 Python 3.x 顯示為<class 'type'>, 僅是顯示方法不同,可以理解為等價(jià),因?yàn)樵赑ython 3.x類(lèi)即類(lèi)型。

參考官方文檔:https://docs.python.org/3/library/stdtypes.html#bltin-type-objects

Type objects represent the various object types. An object's type is accessed by the built-in functiontype(). There are no special operations on types. The standard moduletypesdefines names for all standard built-in types.

Types are written like this:<class'int'>.

再來(lái)進(jìn)行一個(gè)有趣的嘗試:

print(type(type))

在python 2.x 和 3.x 運(yùn)行結(jié)果都是一樣的,type類(lèi)型本身也是類(lèi)(新式類(lèi)和內(nèi)置類(lèi)型的類(lèi)與類(lèi)型已經(jīng)合并),它自己也是type類(lèi)型。

Python中類(lèi)與類(lèi)型的區(qū)別是什么

Python中類(lèi)與類(lèi)型的區(qū)別是什么

5.類(lèi)是Type類(lèi)的實(shí)例

有上文的測(cè)試可以得知:所有的類(lèi)型都是type類(lèi)。從另一個(gè)角度理解,類(lèi)就是type類(lèi)的實(shí)例,所有的新式類(lèi),都是由type類(lèi)實(shí)例化創(chuàng)建而來(lái),并且顯式或隱式繼承自object。

type([1, 2, 3])

得到運(yùn)行結(jié)果:<class 'list'>,說(shuō)明[1, 2, 3]這個(gè)list是list類(lèi)的實(shí)例。

同樣的

type(list)

得到運(yùn)行結(jié)果:<class 'type'>,也可以說(shuō)明list這個(gè)類(lèi)是type類(lèi)的實(shí)例。

通過(guò)調(diào)用__class__屬性可以得到同樣的結(jié)果:

list.__class__
[1, 2, 3].__class__

說(shuō)明類(lèi)對(duì)象是type類(lèi)的實(shí)例。

6.有趣的循環(huán)

前文提到,在Python 3.x 中,所有的類(lèi)都顯式或隱式的派生自object類(lèi),type類(lèi)也不例外。類(lèi)型自身派生自object類(lèi),而object類(lèi)派生自type,二者組成了一個(gè)循環(huán)的關(guān)系。

通過(guò)以下代碼來(lái)驗(yàn)證

isinstance(object, type)
isinstance(type, object)

運(yùn)行結(jié)果:

Python中類(lèi)與類(lèi)型的區(qū)別是什么

看完上述內(nèi)容,你們對(duì)Python中類(lèi)與類(lèi)型的區(qū)別是什么有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI