2017-02-25 73 views
3

一位朋友最近問道:「CPython解釋器如何實際處理OOP(面向對象編程)?」。CPython解釋器如何處理OOP

這個問題最終使我困惑,我的理解C是不是面向對象的語言。

我試過Googling it,搜索StackOverflow甚至讀CPython Wiki。但是我找不到任何有用的東西。

class Person: 
    def __init__(self, name, age): 
     self.name = name 
     self.age = age 

    def getInfo(self): 
     return "Name: " + self.name + "\nAge: " + str(self.age) 

# How the heck does CPython handle this? 
personOne = Person("Bob", 34) 
personTwo = Person("Rob", 26) 

print(personOne.getInfo()) 
print(personTwo.getInfo()) 

所以現在我真的很想知道!如果CPython解釋器本身不是面向對象的,那麼CPython解釋器如何處理對象?

回答

5

Python的OOP實現的全部複雜性遠遠超出了一個堆棧溢出答覆的範圍,但它可以提供一個概述。這將覆蓋很多細節,如元類,多繼承,描述符和C級API。不過,它應該讓你瞭解爲什麼實施這樣的事情是可能的,以及對它如何完成的總體印象。如果您想了解詳細信息,請瀏覽CPython source code


喜歡你Person類的實例對象包括以下內容:

  • 的字典持有其屬性
  • 其他的東西,這是不相關的,現在,像__weakref__

類也相當簡單。它有

  • 基類
  • 的字典持有其屬性
  • 其他的東西,現在是不相關的,如類名。

當你定義一個class聲明一個類,Python的捆綁起來的指針你拾取基類(或object如果未選一個)和一個字典保持你定義的方法,這就是你的新類對象。它有點像下面的元組

Person = (object, 
      {'__init__': <that __init__ method you wrote>, 
      'getInfo': <that getInfo method you wrote>}, 
      those irrelevant bits we're glossing over) 

但不是元組。 (在C水平,這個紀錄是差不多,但不完全,實現爲一個結構。)


當您創建類的實例,巨蟒捆綁在一起的一個指針類,併爲新字典實例的屬性,這就是你的實例。它有點像下面的元組:

personOne = (Person, {}, those irrelevant bits we're glossing over) 

但是,不是元組。同樣,它幾乎但不完全是作爲C級結構實現的。

然後運行__init__,通過__init__新實例,你給你的類提供任何其他參數:

Person.__init__(personOne, "Bob", 34) 

屬性分配被轉換爲設置在對象的字典條目,所以分配在__init__

def __init__(self, name, age): 
    self.name = name 
    self.age = age 

原因字典在以下狀態結束:

{'name': 'Bob', 'age': 34} 

當你調用personOne.getInfo(),巨蟒看起來personOne的字典,那麼它的類的字典,那麼它的父類的字典,等等,直到它找到了'getInfo'鍵的條目。關聯的值將是getInfo方法。如果該方法在類字典中找到,則Python將插入personOne作爲第一個參數。 (知道如何插入該參數的詳細信息在descriptor protocol中。)

6

下面是一個小小的思考實驗:你的CPU根本不是「面向對象」的。相反,它只能執行「將寄存器1添加到寄存器2並將結果放入寄存器3」以及「如果寄存器5大於零,然後執行該goto語句」等指令。然而不知何故,CPU可以運行Python和其他面向對象的語言。怎麼樣?