2012-04-11 90 views
7

python中的每個類都從類的「對象」繼承。我想知道'對象'類實現的內部機制。爲什麼'object'類不能被分配任何用戶屬性?我確信它與內存管理有關,但如果用戶想要自己實現內存管理,爲什麼他不能在Python中重寫'object'類呢?這是基於我的興趣,並希望知道哪些可能沒有任何編程應用程序,但很高興知道該語言本身的內部特徵。爲什麼'對象'類沒有用戶設置屬性

+2

實際上,在Python 2.x下,只有新的類繼承自''object''。 (好吧,在Python 3.x中,但所有的類都是新式的,所以沒有提及它)。 – 2012-04-11 20:23:59

+1

這不是一個downvote偉大的理由 - 但一個好的地方給教育提問者的答案...似乎是一個深思熟慮和有效的問題給我。 +1 – ImGreg 2012-04-11 20:27:57

+1

傑克,你能澄清一下你是否在向對象類或該類的實例添加屬性? – 2012-04-11 20:54:43

回答

1

如果我必須從第一原理得出的推理,我可能會考慮一下在__slots__機制的條款。某些種類只需要很少的屬性,而且每個實例的屬性集總是固定的,所以像用戶屬性能力這樣的「字典」的靈活性會浪費cpu(查找動態命名的屬性)和空間(空字典的開銷,小但非零),如果有大量的實例,這可能真的會加起來很多的開銷。

當然這正是__slots__機制解決的問題。在對象上爲空間中定義的屬性分配空間。如果有__dict__屬性,則可以在那裏找到無插槽屬性,如果沒有__dict__屬性,則既不會獲取不需要的字典對象(除實例本身之外的其他堆對象)的動態屬性或開銷。

至於爲什麼object本身不具有插槽__dict__,那麼,即使一個子類表示,他們並沒有需要__dict__插槽,如果他們從一類確實,那麼實例繼承必須仍然有__dict__;如果object__dict__那麼絕對每個班級也會付出__dict__的價格,即使他們不需要它。

取而代之;子類得到__dict__(和__weakref__,出於類似的原因),除非它們自己定義了__slots__類屬性。

爲什麼你需要一個簡單的ol實例object呢?你只需要一包屬性?那麼使用dict。如果你實際上需要某種具有行爲和屬性的對象,那麼你無論如何都要創建一個子類。

關於我可以想象使用object()而不是object的子類的唯一原因是實例唯一感興趣的特徵是它的身份。這將拿出當一個函數接受參數,併爲其中None或其他一些明顯的標記值應被理解爲從默認的不同:

BAR_DEFAULT = object() 
def foo(bar=BAR_DEFAULT): 
    if bar is BAR_DEFAULT: 
     #... 

在這種情況下,你既不需要也不特別想在實例屬性object,

3

C中定義的類型不能擁有用戶分配的屬性。如果您想全球替換object,則需要遍歷現有的每個類,然後替換__builtin__.object以捕獲所有將來的類創建。即使這樣也不可靠,因爲舊對象可能會綁定在其他地方。

3

這已在StackOverflow上討論過,但我無法找到討論來鏈接它。

我不知道的原因是因爲我想簡化這個例子:

class Box(object): 
    pass 

box = Box() 
box.a = "some value" 
box.b = 42 

這裏我使用box作爲一種字典,一個其中的鍵只能是標識符。我這樣做是因爲寫出box.abox["a"]更方便。

我想這樣做:

box = object() 
box.a = "some value" # doesn't work 

的原因是,object在Python中的所有對象的根。 object所具有的任何屬性必須位於任何派生類型中。如果你想製作一個包含大量對象的大列表,你希望它們儘可能小,以免內存不足。所以object本身很小。

編輯:我發現我試圖記住鏈接:

struct objects in python

相關問題