2017-02-18 23 views
0

在我看來,特定類的每個實例都有自己的字典。當存在大量相同結構的類對象時,這可能會浪費很多空間。這實際上是這種情況,還是底層機制更有效,只有在明確要求時才創建對象的字典。 我正在考慮一個應用程序,我可能有一個非常大的數量,可能是數百萬的對象,我是否應該避免使用類,而是使用具有命名常量的序列作爲索引?類對象的數據效率

+1

百萬是不是一個很大的數字,但你應該檢查'__slots__'。例如在這裏:http://stackoverflow.com/questions/472000/usage-of-slots –

+0

@Paul Hankin這應該是一個答案,然後我可以upvoted它。這正是我尋找的答案。 –

+0

它還具有額外的好處,即只能訪問__slots__變量中指定的元素,因此可以更快地檢測到輸入錯誤。這在Python文檔中應該更加突出。 –

回答

1

如果你想減少開銷,你有兩個選擇取決於你實際需要什麼。

如果您需要類結構,那麼您應該考慮使用__slots__。這將避免__dict__,但仍允許您擁有方法,屬性等。你將失去動態添加屬性的能力(你只能被列爲__slots__)。

如果您只想爲對象「存儲」並且不需要方法和類似方法,則可以使用collections.namedtuple。這些爲他們的物品提供了「類似」的界面,並且應該非常節省空間。

例如,僅僅有兩個屬性「姓氏」和「姓名」一類可以實現爲:

class Person(object): 
    __slots__ = ['firstname', 'lastname'] 

    def __init__(self, firstname, lastname): 
     self.firstname = firstname 
     self.lastname = lastname 

    def __repr__(self): 
     return '{self.__class__.__name__}({self.firstname!r}, {self.lastname!r})'.format(self=self) 

>>> p = Person('Tom', 'Riddle') 
>>> p 
Person('Tom', 'Riddle') 
>>> p.firstname 
'Tom' 

或namedtuple:

>>> from collections import namedtuple 

>>> Person = namedtuple('Person', 'firstname, lastname') 

>>> p = Person('Tom', 'Riddle') 
>>> p 
Person(firstname='Tom', lastname='Riddle') 
>>> p.firstname 
'Tom' 
+0

在我看來,阻止動態添加成員往往是一種好處。我不知道namedtuple,否則會認爲這是一個很好的解決方案,但__slots__看起來更好。 –

+0

@ChrisBarry兩者都有它們的用例。我同意'__slots__'是優越的(它們允許方法和真實的屬性),但是在某些情況下,你只需要一個「class-like」不變的存儲容器,然後'namedtuple'是一個可行的選擇。 – MSeifert

-1

這取決於你想要存儲在每個對象中的數據,但在大多數情況下列表應該這樣做。