Ich habe eine Klasse, die nur Felder und keine Methoden enthält, wie folgt:
class Request(object):
def __init__(self, environ):
self.environ = environ
self.request_method = environ.get('REQUEST_METHOD', None)
self.url_scheme = environ.get('wsgi.url_scheme', None)
self.request_uri = wsgiref.util.request_uri(environ)
self.path = environ.get('PATH_INFO', None)
# ...
Dies könnte leicht in ein Diktat übersetzt werden. Die Klasse ist flexibler für zukünftige Ergänzungen und könnte schnell sein __slots__
. Wäre es also von Vorteil, stattdessen ein Diktat zu verwenden? Wäre ein Diktat schneller als eine Klasse? Und schneller als eine Klasse mit Slots?
python
oop
class
dictionary
Deamon
quelle
quelle
dict
kann es sinnvoll sein, eine Klasse abzuleiten . ordentlicher Vorteil: Wenn Sie debuggen, sagenprint(request)
Sie einfach und Sie werden sofort alle Statusinformationen sehen. Mit dem klassischeren Ansatz müssen Sie Ihre benutzerdefinierten__str__
Methoden schreiben , was scheiße ist, wenn Sie es die ganze Zeit tun müssen.Antworten:
Warum sollten Sie dies zu einem Wörterbuch machen? Was ist der Vorteil? Was passiert, wenn Sie später Code hinzufügen möchten? Wohin würde Ihr
__init__
Code gehen?Klassen dienen zum Bündeln verwandter Daten (und normalerweise von Code).
Wörterbücher dienen zum Speichern von Schlüssel-Wert-Beziehungen, wobei normalerweise alle Schlüssel vom gleichen Typ sind und alle Werte auch vom einen Typ sind. Gelegentlich können sie nützlich sein, um Daten zu bündeln, wenn die Schlüssel- / Attributnamen nicht alle im Voraus bekannt sind. Dies ist jedoch häufig ein Zeichen dafür, dass etwas mit Ihrem Design nicht stimmt.
Halten Sie dies eine Klasse.
quelle
__init__
. Aber Sie haben Recht: Ich würde mich von Dingen trennen, die zusammengehören.where would your __init__ code go?
betrifft. Es könnte einen weniger erfahrenen Entwickler davon überzeugen, dass nur Klassen verwendet werden sollen, da in einem Wörterbuch keine init- Methode verwendet wird. Absurd.Verwenden Sie ein Wörterbuch, es sei denn, Sie benötigen den zusätzlichen Mechanismus einer Klasse. Sie können auch einen
namedtuple
für einen hybriden Ansatz verwenden:Die Leistungsunterschiede hier sind minimal, obwohl ich überrascht wäre, wenn das Wörterbuch nicht schneller wäre.
quelle
Eine Klasse in Python ist ein Diktat darunter. Sie bekommen zwar etwas Aufwand mit dem Klassenverhalten, können es aber ohne einen Profiler nicht bemerken. In diesem Fall glaube ich, dass Sie von der Klasse profitieren, weil:
quelle
Ich denke, dass die Verwendung jedes einzelnen viel zu subjektiv ist, als dass ich mich darauf einlassen könnte, also bleibe ich einfach bei Zahlen.
Ich habe die Zeit verglichen, die zum Erstellen und Ändern einer Variablen in einem Diktat, einer new_style-Klasse und einer new_style-Klasse mit Slots benötigt wird.
Hier ist der Code, den ich zum Testen verwendet habe (es ist ein bisschen chaotisch, aber es macht den Job.)
Und hier ist die Ausgabe ...
Erstellen...
Variable ändern ...
Wenn Sie also nur Variablen speichern, benötigen Sie Geschwindigkeit und müssen nicht viele Berechnungen durchführen. Ich empfehle die Verwendung eines Diktats (Sie können immer nur eine Funktion erstellen, die wie eine Methode aussieht). Aber wenn Sie wirklich Klassen brauchen, denken Sie daran - verwenden Sie immer __ Slots __ .
Hinweis:
Ich habe die 'Klasse' mit beiden getestet mit den Klassen new_style als auch old_style getestet. Es stellt sich heraus, dass old_style-Klassen schneller zu erstellen, aber langsamer zu ändern sind (nicht viel, aber bedeutsam, wenn Sie viele Klassen in einer engen Schleife erstellen (Tipp: Sie machen es falsch)).
Auch die Zeiten zum Erstellen und Ändern von Variablen können auf Ihrem Computer unterschiedlich sein, da meine alt und langsam sind. Stellen Sie sicher, dass Sie es selbst testen, um die "echten" Ergebnisse zu sehen.
Bearbeiten:
Ich habe das Namedtuple später getestet: Ich kann es nicht ändern, aber um die 10000 Samples (oder ähnliches) zu erstellen, hat es 1,4 Sekunden gedauert, sodass das Wörterbuch tatsächlich das schnellste ist.
Wenn ich die Diktatfunktion so ändere , dass sie die Schlüssel und Werte enthält und das Diktat anstelle der Variablen zurückgibt, die das Diktat enthält, wenn ich es erstelle, gibt es mir 0,65 statt 0,8 Sekunden.
Das Erstellen ist wie eine Klasse mit Slots und das Ändern der Variablen ist am langsamsten (0,17 Sekunden). Verwenden Sie diese Klassen also nicht . Gehen Sie für ein Diktat (Geschwindigkeit) oder für die vom Objekt abgeleitete Klasse ('Syntax Candy')
quelle
dict
(ohne überschriebene Methoden, denke ich?). Funktioniert es genauso wie eine neue Klasse, die von Grund auf neu geschrieben wurde?Ich stimme @adw zu. Ich würde niemals ein "Objekt" (im OO-Sinne) mit einem Wörterbuch darstellen. Wörterbücher aggregieren Name / Wert-Paare. Klassen repräsentieren Objekte. Ich habe Code gesehen, in dem die Objekte mit Wörterbüchern dargestellt werden, und es ist unklar, wie die tatsächliche Form der Sache ist. Was passiert, wenn bestimmte Namen / Werte nicht vorhanden sind? Was den Kunden daran hindert, überhaupt etwas einzubringen. Oder zu versuchen, überhaupt etwas herauszuholen. Die Form der Sache sollte immer klar definiert sein.
Bei der Verwendung von Python ist es wichtig, diszipliniert zu bauen, da die Sprache dem Autor viele Möglichkeiten bietet, sich selbst in den Fuß zu schießen.
quelle
Ich würde eine Klasse empfehlen, da es sich um alle Arten von Informationen handelt, die mit einer Anfrage verbunden sind. Wenn man ein Wörterbuch verwenden würde, würde ich erwarten, dass die gespeicherten Daten weitaus ähnlicher sind. Eine Richtlinie, der ich mich selbst folge, ist, dass ich ein Wörterbuch verwende, wenn ich den gesamten Satz von Schlüssel-> Wertepaaren durchlaufen und etwas tun möchte. Andernfalls sind die Daten anscheinend weitaus strukturierter als eine grundlegende Schlüssel-> Wertzuordnung, was bedeutet, dass eine Klasse wahrscheinlich eine bessere Alternative wäre.
Bleib also bei der Klasse.
quelle
Wenn alles, was Sie erreichen möchten, Syntax-Bonbons wie
obj.bla = 5
anstelle von istobj['bla'] = 5
, insbesondere wenn Sie dies häufig wiederholen müssen, möchten Sie möglicherweise eine einfache Container-Klasse wie in Martineaus Vorschlag verwenden. Trotzdem ist der Code dort ziemlich aufgebläht und unnötig langsam. Sie können es so einfach halten:Ein weiterer Grund für den Wechsel zu
namedtuple
s oder einer Klasse mit__slots__
könnte die Speichernutzung sein. Dikte benötigen deutlich mehr Speicher als Listentypen, daher sollte dies ein Punkt sein, über den man nachdenken sollte.In Ihrem speziellen Fall scheint es jedoch keine Motivation zu geben, von Ihrer aktuellen Implementierung abzuweichen. Sie scheinen nicht Millionen dieser Objekte zu verwalten, daher sind keine von Listen abgeleiteten Typen erforderlich. Und es enthält tatsächlich eine funktionale Logik innerhalb der
__init__
, so dass Sie auch nicht mit bekommen solltenAttrDict
.quelle
types.SimpleNamespace
(verfügbar seit Python 3.3) ist eine Alternative zum benutzerdefinierten AttrDict.Möglicherweise können Sie Ihren Kuchen auch essen. Mit anderen Worten, Sie können etwas erstellen, das die Funktionalität einer Klassen- und einer Wörterbuchinstanz bietet. Siehe die ActiveState'sLesen Sie das Rezept und kommentieren Sie, wie Sie dies tun können.
Wenn Sie eine reguläre Klasse zu verwenden entscheiden , anstatt eine Unterklasse, habe ich das gefunden Tʜᴇ sɪᴍᴘʟᴇ ʙᴜᴛ ʜᴀɴᴅʏ „ᴄᴏʟʟᴇᴄᴛᴏʀ ᴏғ ᴀ ʙᴜɴᴄʜ ᴏғ ɴᴀᴍᴇᴅ sᴛᴜғғ“ ᴄʟᴀss Rezept (von Alex Martelli) zu sehr flexibel und nützlich für die Art von Sache , die es sieht so aus, als ob Sie es tun (dh einen relativ einfachen Aggregator von Informationen erstellen). Da es sich um eine Klasse handelt, können Sie ihre Funktionalität problemlos durch Hinzufügen von Methoden erweitern.
Abschließend sollte angemerkt werden, dass die Namen von Klassenmitgliedern legale Python-Bezeichner sein müssen, Wörterbuchschlüssel jedoch nicht. Ein Wörterbuch würde diesbezüglich mehr Freiheit bieten, da Schlüssel alles sein können, was hashbar ist (sogar etwas, das keine Zeichenfolge ist).
Aktualisieren
Eine Klasse
object
(die keine hat__dict__
) mit dem NamenSimpleNamespace
(die eine hat) wurde demtypes
Modul Python 3.3 hinzugefügt und ist eine weitere Alternative.quelle
Ich empfehle eine Klasse. Wenn Sie eine Klasse verwenden, können Sie wie gezeigt einen Tipphinweis erhalten. Und Klassenunterstützung wird automatisch vervollständigt, wenn Klasse ein Funktionsargument ist.
quelle