tft每日頭條

 > 生活

 > python class的用法和作用

python class的用法和作用

生活 更新时间:2025-01-08 09:23:21

在Python的學習中我們肯定會聽到一句話:「python中一切皆對象」

如果再接着學習下去的話,我們就會接觸到Python中的type, object, class等概念。網上也有不少文章闡述了這三者之間的關系,但是在看了大部分文章之後我還是似懂非懂,感覺就像有什麼東西卡在了喉嚨一直咽下不去一樣。

于是為了能讓自己晚上順利吃上飯,我立馬對着搜索引擎就是一頓操作,終于趕在外賣小哥打響我電話之前,咽下了這幾個如鲠在喉的概念,舒服!
趁着外賣小哥上樓這會,分享下我學習研究後的理解吧。

python中的對象

python作為面向對象的語言之一,符合一切基于面向對象理念的設計。在面向對象的體系中,對象存在着兩種關系。

繼承關系

簡單來說即子類繼承于父類,子類擁有其自身及父類的方法和屬性,同名的子類方法和屬性将會覆蓋父類的方法和屬性。
語義化的理解栗子為:「蛇」類繼承自「爬行動物類」,所以「蛇是一種爬行動物」,英文說「snake is a kind of reptile」
在python中的繼承關系可以簡單表示如下:

class Reptile:     title = '爬行動物'     def crawl(self):         print(self.title) class Snake(Reptile):     def crawl_a(self):         print(self.title) p = Snake() p.crawl()  # 爬行動物 p.crawl_a() # 爬行動物 print(p.title) # 爬行動物

上面這個栗子中,子類Snake繼承了父類Reptile的title屬性和crawl方法,使得類B的實例對象b能調用父類的a屬性和get方法。
另外,如果要查看一個類(class)的父類,可以使用class_name.__bases__的形式來查看。

Snake.__bases__ # (<class '__main__.Reptile'>,)

實例化關系

如果繼承關系好比父與子的關系,實例化關系則是一個從抽象到具體的過程。實例是某個類中具體的個體的表示。
語義化的理解栗子為:「小p是一條蛇」,「蛇」是一個分類,「小p」則是這個分類中的一個具體的個體。英文說「小p is an instance of snake」

class Snake:     pass p = Snake() # p是Snake類的實例對象

如果想要查看一個對象是由哪個類實例化而來,可以使用type() 或 object_name.__class__來查看。表示對象屬于什麼類型。

type(p) # <class '__main__.Snake'> 表示對象p是由類Snake實例化而來,p的類型是Snake p.__class__ # <class '__main__.Snake'> 表示對象p是由類Snake實例化而來,p的類型是Snake

探究對象的秘密

有了以上的基礎,我們就可以一步一步來探究python中對象潛藏着一些秘密了。嘿嘿嘿~

python class的用法和作用(在學pythontypeobject)1


先看看下面樸而不素的代碼:

class A:     pass a = A() print(A.__bases__) # (<class 'object'>,) print(object.__bases__) # () print(type(a)) # <class '__main__.A'> print(type(A)) # <class 'type'> print(type(object)) # <class 'type'> print(type.__bases__) # (<class 'object'>,)

通過上面的很簡單的代碼,運用一眼洞穿法,我們可以根據每個打印語句的結果得到一些簡單的觀察結論:

  1. 如果定義一個類時沒有指定繼承哪個類,則默認繼承object類
  2. object類的父類為空,說明object類位于繼承關系鍊的頂端,object類是Python中所有類的父類,可以說object是python中的頂端類
  3. 對象a由類A實例化而來,a的類型為A,這個比較容易理解。
  4. 根據3的觀察結果,同樣的觀察手法運用在類A上,觀察到類A是由type這個類實例化而來,類A的類型為type,說明類A是一個類的同時也是一個對象(類A是類type的實例化對象)。這裡可能有點暈但是請先接着看下去吧。
  5. 根據3的觀察結果,同樣的觀察手法運用在頂端類object上,觀察到object這個頂端類也是由type這個類實例化而來,類object的類型也為type,也說明object作為一個類的同時也是一個對象。
  6. 類`type`作為實例化類`A`和類`object`的類,其父類為`object`

看完上面的這些觀察結論,相信有一部分童鞋已經兩眼發懵了,什麼類A是一個類也是一個對象,object類的類型是type,而type類的父類又是object…blablabla

python class的用法和作用(在學pythontypeobject)2

诶,莫方莫方,俗話說無圖言*,這裡先來一張圖簡單表示一下這幾者的關系,舒緩一下情緒:

python class的用法和作用(在學pythontypeobject)3

python中type,class,object三者關系圖


下面我們就可以開始看圖寫作文啦~
藍色箭頭由實例對象指向實例化它的類,紅色箭頭由子類指向父類。值得注意的是,這個圖有幾個關鍵的地方:

  • 類(如class A, class object)都是由type這個類實例化而來的,即所有類(class)對象的類型都是type
  • type這個類也是由type自己實例化而來的(圖中type處指向自身的部分),即type類的類型也為type
  • type類的父類是object類

有了以上的鋪墊,我們可以知道一個最普通的實例對象鍊是這樣子的:
type --實例化--> object --衍生--> class --實例化--> a(具體對象)
這部分都是比較好理解的,但關鍵的問題是 ———— object類作為type類的父類,怎麼會是由type類實例化出來的?還有type類居然是由type自己實例化出來的?這都是什麼操作?

python class的用法和作用(在學pythontypeobject)4


個人認為,這兩個問題解決了才能更好地理解type、class、object三者的關系。然而要知道為什麼python是這樣設計的,最好的做法便是去翻他們的源碼啦。不過在翻之前,其實已經有一些大佬對python的源碼做了解讀,通過搜索引擎認真找尋便可找到想要的答案。python的底層是C的實現,下面的源碼如果看不懂的話請别在意,因為不妨礙理解。

(⊙o⊙)

我們可以看看在源碼中,type類和object類分别是什麼:
type類實際上是:

#define PyVarObject_HEAD_INIT(type, size)     1, type, size, PyTypeObject PyType_Type = {     PyVarObject_HEAD_INIT(&PyType_Type, 0)     "type",                                     /* tp_name */     sizeof(PyHeapTypeObject),                   /* tp_basicsize */     sizeof(PyMemberDef),                        /* tp_itemsize */     0,                                          /* tp_base */     ... }

object類實際上是:

PyTypeObject PyBaseObject_Type = {     PyVarObject_HEAD_INIT(&PyType_Type, 0)     "object",                                   /* tp_name */     sizeof(PyObject),                           /* tp_basicsize */     0,                                          /* tp_itemsize */     0,                                          /* tp_base */     ... }

這兩個類結構體中的各項的具體含義這裡不做深究,因為不在本文研究範圍内。我們隻需要關注這兩個結構中的第一行:

PyVarObject_HEAD_INIT(&PyType_Type, 0)

它表示這個類結構的對象類型。能看出來object 類 和 type 類的對象類型都是 &PyType_Type,而 PyType_Type 正是底層表示type類的結構體!
這兩個結構體就說明了:
object類将類型(即誰實例化了這個類)設置成了type類,type類将類型設置成了自己!這其實是python底層實現的一個小小的trick~

然後在type類的初始化過程中,執行了如下代碼:

type->tp_base = &PyBaseObject_Type;

轉換成python為

type.__base__ = (object,) 

表示将object類指定為type類的父類,這不就是第二個問題的答案所在嗎?
源碼看到這裡,前面的兩個問題就已經全部解決了,我們可以開始全面總結一下type,class,object的關系了。

總結

type,class,object三者關系:

  • object類是所有類(class)的父類,包括type類,object類的父類為空。
  • type類是所有類的類型,即為所有類(class)都可由type實例化而來,包括type類自己。
    将上面的關系總結成一張圖就是:
    pyhton三者關系全
後記&引用

寫到這裡,python中這三者的關系探究就差不多了,隻能說技術寫作不是一件容易的事情,前後改了不少東西還是不那麼讓自己滿意,但是已經按照自己的意思給表述出來了,希望之後能寫得更順手一些。話說外賣小哥已經在門口等了我5分鐘了,寫文章死了那麼多腦細胞,胃口一定不錯吧哈哈。

python class的用法和作用(在學pythontypeobject)5


參考文章:

  • 詳解Python中的type和object
  • Python 的 type 和 object 之間是怎麼一種關系?
  • 在 Python 中,為什麼 type 類對象自身的類型是 type?
讀後三連⭐️

如果你覺得這篇内容對你有幫助,我想邀請你幫我三個小忙:

  1. 點贊,讓更多的人也能看到這篇内容(這對我真的很重要)
  2. 關注公衆号「py一下」,不定期分享原創知識,python/後端/業務/數據結構與算法等
  3. 也多看看其他文章


python class的用法和作用(在學pythontypeobject)6

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved