• <strike id="6sogq"><s id="6sogq"></s></strike>
  • <strike id="6sogq"></strike>

    千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

    400-811-9990
    手機(jī)站
    千鋒教育

    千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

    千鋒教育

    掃一掃進(jìn)入千鋒手機(jī)站

    領(lǐng)取全套視頻
    千鋒教育

    關(guān)注千鋒學(xué)習(xí)站小程序
    隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

    上海
    • 北京
    • 鄭州
    • 武漢
    • 成都
    • 西安
    • 沈陽(yáng)
    • 廣州
    • 南京
    • 深圳
    • 大連
    • 青島
    • 杭州
    • 重慶
    當(dāng)前位置:成都千鋒IT培訓(xùn)  >  技術(shù)干貨  >  Python對(duì)象的方法調(diào)用時(shí)發(fā)生了什么?

    Python對(duì)象的方法調(diào)用時(shí)發(fā)生了什么?

    來(lái)源:千鋒教育
    發(fā)布人:xqq
    時(shí)間: 2023-10-17 14:10:23

    一、Python對(duì)象的方法調(diào)用時(shí)發(fā)生了什么

    1.尋找Eat

    catObj尋找一個(gè)叫Eat的東西,這東西可能是任意對(duì)象,名字就叫Eat(暫且先忘了Cat類里定義了什么),這其實(shí)就涉及到Python屬性訪問(wèn)順序了:

    __getattribute__數(shù)據(jù)描述符對(duì)象屬性類屬性非數(shù)據(jù)描述符父類屬性__getattr__()

    為了更簡(jiǎn)單得去理解,本文只關(guān)注對(duì)象屬性,類屬性,父類屬性這三點(diǎn)。

    首先從對(duì)象屬性去找:

    catObj對(duì)象有沒(méi)有名為Eat這個(gè)屬性?從上面定義的Cat類看顯然是沒(méi)有,這個(gè)對(duì)象只有一個(gè)屬性name,可打印__dict__查看對(duì)象的屬性。

    print(catObj.__dict__)

    # 打印結(jié)果:

    # {‘name’: ‘Godeng’}

    catObj.food = “Fish”

    # 打印結(jié)果:

    # {‘name’: ‘Godeng’, ‘food’: ‘Fish’}

    對(duì)象添加一個(gè)屬性,它就會(huì)進(jìn)對(duì)象的__dict__里,歸根結(jié)底都是字典訪問(wèn)。

    對(duì)象屬性找不到,去類屬性找,從catObj對(duì)象的__class__屬性即可索引到類:

    Cat類有沒(méi)有名為Eat這個(gè)屬性?從上面定義的Cat類看,顯然是有的,且類也是對(duì)象,也可通過(guò)打印__dict__觀察它的屬性。

    print(Cat.__dict__)

    # 打印結(jié)果:

    # {…’Eat’: ,

    # ‘__init__’: …}

    Eat和__init__赫然在列,而且Eat和__init__是一個(gè)質(zhì)樸得不能再質(zhì)樸的函數(shù),函數(shù),函數(shù)。

    如果在類屬性找不到的話,就會(huì)嘗試去父類屬性尋找,相似的過(guò)程。

    那么到此,尋找到了一個(gè)名為Eat的函數(shù)。

    2.包裝成Eat方法&調(diào)用

    def Eat(self):

    ??? print(“Cat is eating”)

    從catObj對(duì)象一路尋找到的Eat函數(shù)是長(zhǎng)這樣的,但它并非最終的返回的方法。將函數(shù)與對(duì)象進(jìn)行包裝后的產(chǎn)物,才是方法。

    class Method(object):

    ??? def __init__(self, obj, func):

    ?????? self.__self__ = obj

    ?????? self.__func__ = func

    ??? def __call__(self, *args, **kwargs):

    ?????? self.__func__(self.__self__, *args, **kwargs)

    catObj = Cat(“Godeng”)

    eatMethod = Method(catObj, Cat.Eat)

    eatMethod()

    上面是模擬方法的結(jié)構(gòu)和大致產(chǎn)生調(diào)用過(guò)程,方法對(duì)象自身會(huì)引用Cat類函數(shù)Eat,和eatObj對(duì)象,并方法對(duì)象被調(diào)用時(shí)(__call__調(diào)用時(shí)),自動(dòng)把eatObj對(duì)象作為了該函數(shù)的self參數(shù)。

    并非方法本身蘊(yùn)含了什么不可告人的魔力,catObj.eat獲取的其實(shí)就是類似上例的Method對(duì)象,從使用形式來(lái)看它提供的一個(gè)顯著特點(diǎn)是,他就像一個(gè)不需要傳self參數(shù)的函數(shù)。

    方法&類函數(shù)引用上的區(qū)別:

    類函數(shù)Cat.Eat是一個(gè)普通函數(shù)對(duì)象,它被Cat類引用。

    catObj.Eat是一個(gè)方法對(duì)象,它引用了類函數(shù)Cat.Eat和catObj對(duì)象,它并不是像類函數(shù)那樣有被Cat類或catObj對(duì)象引用的一個(gè)恒久的對(duì)象,每次catObj.Eat的調(diào)用都會(huì)走一遍上述流程,產(chǎn)生一個(gè)新的方法對(duì)象返回。

    # 生成了一個(gè)新的方法對(duì)象,這句執(zhí)行完畢后方法對(duì)象會(huì)被銷毀

    catObj.Eat()

    # 生成了一個(gè)新的方法對(duì)象, 并由eatMethod引用,方法對(duì)象不會(huì)被銷毀

    eatMethod = catObj.Eat

    # 刪除eatMethod的引用,方法對(duì)象隨之被銷毀

    eatMethod = None

    延伸閱讀:

    二、如何從父類們找類函數(shù)

    Python是門(mén)多繼承語(yǔ)言,在上面catObj尋找Eat到它的類的時(shí)候,如果Cat類沒(méi)有定義Eat,會(huì)嘗試向父類尋找Eat。

    class Monster(object):

    ??? def Eat(self):

    ?????? print(“Monster Eat”)

    class Pet(object):

    ??? def Eat(self):

    ?????? print(“Pet Eat”)

    class Cat(Pet, Monster):

    ??? def __init__(self, name):

    ?????? self.name = name

    假如Cat沒(méi)定義Eat,它的兩個(gè)父類Pet和Monster的都定義了Eat,那就是先在哪個(gè)父類找到Eat,那么就返回哪個(gè)父類的Eat,也即是取決于先從Pet類找,還是先從Monster類找。

    這就涉及到Python一個(gè)老生常談的概念,方法解析順序(mro),它確定了這個(gè)順序,它的具體規(guī)則會(huì)隨著Python版本迭代而迭代,如Py2是深度優(yōu)先和Py3是廣度優(yōu)先,具體在此就不展開(kāi)了。

    可通過(guò)打印類的mro來(lái)觀察類的執(zhí)行順序。

    print(Cat.mro())

    print(Cat.Eat)

    # 打印結(jié)果:

    # [, , , ]

    #

    聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。

    猜你喜歡LIKE

    sql server2012r2所在服務(wù)器做端口限制,需要開(kāi)放什么端口才能繼續(xù)訪問(wèn)數(shù)據(jù)庫(kù)?

    2023-10-17

    Oracle有什么優(yōu)勢(shì)和劣勢(shì)?

    2023-10-17

    CSS 隱藏頁(yè)面元素有哪些方法?

    2023-10-17

    最新文章NEW

    數(shù)據(jù)庫(kù)聚集索引非聚集索引實(shí)現(xiàn)上有哪些區(qū)別?

    2023-10-17

    開(kāi)發(fā)web應(yīng)用,好的開(kāi)發(fā)流程是怎么樣的?

    2023-10-17

    為什么說(shuō)Gradle是Android進(jìn)階繞不去的坎?

    2023-10-17

    相關(guān)推薦HOT

    更多>>

    快速通道 更多>>

    最新開(kāi)班信息 更多>>

    網(wǎng)友熱搜 更多>>