2017-02-18 1 views
0

Es scheint mir, dass jede Instanz einer bestimmten Klasse ihr eigenes Wörterbuch hat. Dies könnte viel Platz verschwenden, wenn eine große Anzahl von identisch strukturierten Klassenobjekten vorhanden ist. Ist dies tatsächlich der Fall oder ist der zugrundeliegende Mechanismus effizienter, erstellen Sie nur das Wörterbuch eines Objekts, wenn es explizit angefordert wird. Ich überlege mir eine Anwendung, in der ich möglicherweise eine sehr große Anzahl von Objekten habe, möglicherweise in Millionen, sollte ich die Verwendung einer Klasse vermeiden und stattdessen eine Sequenz mit einer benannten Konstante als Index verwenden?Dateneffizienz von Klassenobjekten

+1

Millions ist eine sehr große Zahl nicht, aber Sie sollten sich '__slots__' anschauen. Zum Beispiel hier: http://stackoverflow.com/questions/472000/usage-of-slots –

+0

@Paul Hankin Das sollte eine Antwort gewesen sein, dann hätte ich es upvolotiert haben können. Es ist genau die Antwort, nach der ich gesucht habe. –

+0

Es hat den zusätzlichen Vorteil, dass nur auf Elemente zugegriffen werden kann, die in der Variablen __slots__ benannt sind, sodass Tippfehler früher erkannt werden. Dies sollte in der Python-Dokumentation wirklich viel prominenter sein. –

Antwort

1

Wenn Sie den Overhead reduzieren möchten, haben Sie zwei Optionen, je nachdem, was Sie tatsächlich benötigen. Wenn Sie eine klassenähnliche Struktur benötigen, sollten Sie in Betracht ziehen, __slots__ zu verwenden. Dies wird die vermeiden, aber Sie können immer noch Methoden, Eigenschaften und so weiter haben. Sie verlieren die Möglichkeit, Attribute dynamisch hinzuzufügen (Sie sind auf die als __slots__ aufgeführten Attribute beschränkt).

Wenn Sie nur einen "Speicher" für Objekte wünschen und keine Methoden und ähnliches benötigen, können Sie collections.namedtuple verwenden. Diese bieten eine "klassenähnliche" Schnittstelle zu ihren Elementen und sollten ziemlich platzsparend sein.

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' 

oder als namedtuple:

Zum Beispiel eine Klasse, die nur zwei Attribute „Nachname“ und „Vorname“ könnte als implementiert werden

>>> from collections import namedtuple 

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

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

Es ist meiner Meinung nach öfter ein Vorteil, wenn man Mitglieder dynamisch nicht hinzufügen kann. Ich wusste nichts über Nametuple und hätte es sonst für eine gute Lösung gehalten, aber __slots__ scheint überlegen zu sein. –

+0

@ChrisBarry Beide haben ihre Anwendungsfälle. Ich stimme zu, dass "__slots__" besser ist (sie erlauben Methoden und reale Eigenschaften), aber in einigen Fällen wollen Sie nur einen "klassenähnlichen" unveränderlichen Speichercontainer und dann ist "namedtuple" eine brauchbare Alternative. – MSeifert

-1

Das hängt von den Daten ab, die Sie in jedem Objekt speichern möchten, aber in den meisten Fällen sollten Listen genügen.

Verwandte Themen