2011-06-30 65 views
1

因此,對於writing extension Python文檔說這個:python中的實例變量和屬性之間的區別?

「我們要暴露我們的實例 變量屬性有一個 多種方式做到這一點的 最簡單的方法是定義成員 。定義:

static PyMemberDef Noddy_members[] = { 
    {"first", T_OBJECT_EX, offsetof(Noddy, first), 0, 
    "first name"}, 
    {"last", T_OBJECT_EX, offsetof(Noddy, last), 0, 
    "last name"}, 
    {"number", T_INT, offsetof(Noddy, number), 0, 
    "noddy number"}, 
    {NULL} /* Sentinel */ 
}; 

,並把在 tp_members插槽的定義:

Noddy_members,    /* tp_members */" 

然而,我們已經把實例變量的諾迪結構:

typedef struct { 
    PyObject_HEAD 
    PyObject *first; 
    PyObject *last; 
    int number; 
} Noddy; 

所以我的問題是,爲什麼我們把他們在這兩個地方。我的印象是,這是因爲我們希望類型和實例都具有它們,以便在實例更新後保留類型值。但是,如果是這種情況,如果我們更改類屬性,實例值如何更新?像這樣:

>>> class foo(object): x = 4 
... 
>>> f = foo() 
>>> f.x 
4 
>>> foo.x = 5 
>>> f.x 
5 

回答

1

行,所以我做了我的研究,是的實例變量和屬性是不同的,那是因爲類的實例和類都具有獨立的詞典。如在documentation中所述::

通過調用 類對象(請參見上文)創建類實例。一個類的實例 作爲擁有一本字典是第一 發生在哪個屬性進行搜索 引用實現 命名空間。當一個屬性沒有找到 和實例的類 擁有這個名字的屬性,則 搜索與類 屬性繼續。

所以基本上諾迪結構持有的實例變量。 Noddy_members擁有屬性。此外:

屬性分配和刪除 更新實例的字典裏,從來沒有 類的字典。如果 類有一個SETATTR()或 delattr()方法,這就是所謂的,而不是直接更新實例 字典。

另外:

如果一個類屬性被發現是 一個用戶定義的函數對象或 未結合的用戶定義的方法對象 ,其相關的類是類 (它命名爲c ) 屬性引用 或它的一個基地,它被轉換爲一個綁定的用戶定義的方法 對象,其im_class屬性是C ,其im_s_s elf屬性是 實例。靜態方法和類 方法對象也被轉換, 好像它們已經從 類C檢索;見上面的「類」。 見部分,用於在哪些屬性的 經由其實例 可以從實際上 存儲在類的字典對象不同檢索的類的另一種方法實施描述符 。如果找不到 class屬性,並且 對象的類具有getattr() 方法,則調用該方法以滿足 查找。

2

編寫C擴展是一個複雜的過程,因爲你必須編寫C代碼,你必須提供足夠的信息到Python,以便它可以操縱你的C數據,就好像它是Python數據。你就不得不提到結構的成員兩次:一次是C編譯器知道如何使結構,然後再這樣Python知道哪裏的數據,並且它叫什麼。

C有沒有反省的能力,所以你不能(例如),在運行時獲取一個結構的成員列表。 PyMemberDef的數組提供了這些信息。

+1

另一種說法是,Python無法查看C源代碼並查看struct的成員的名稱和類型。這些信息通常在編譯後的代碼中不存在,所以你必須把它放在那裏讓Python訪問它。 – kindall

相關問題