Python OO-Programmstrukturplanung

8

Ich bin ein Anfänger in OOP und ich möchte ein Programm mit drei Klassen, A, B und C erstellen. Jede Instanz der Klasse wird durch eine Reihe von Merkmalen definiert, Achar1, Achar2 etc.

Das Programm soll Verwendungen erstellen, bestehend aus Element von A, Element von B und Element von C mit Anfangs- und Enddatum. Es gibt Unterklassen von A und B, so dass einige Elemente von A nur mit bestimmten Elementen von B verbunden werden können. Die Hauptfunktionalität des Programms besteht darin, Elemente von A, B und C mit ihren Aributen aufzuführen, Liste verwendet und schlagen neue Verwendungen vor, die die Instanzen der verwendeten Klassen am wenigsten verwenden würden, um Wiederholungen zu vermeiden.

Mein erster Instinkt besteht darin, drei Wörterbücher A, B und C und ein Wörterbuch für die Verwendung zu verwenden. Dies scheint intuitiv und einfach in JSON oder ähnliches zu importieren / exportieren. Ich habe versucht, es neu zu schreiben, um Klassen zu verwenden, aber ich kann keinen Gewinn dabei sehen: es ist schwer (?), Über Instanzen von Klassen zu iterieren, und sie sind im Grunde Wörterbücher, da diese Daten nicht viel mehr brauchen.

Was mache ich falsch? Was kann ich durch den Wechsel von Wörterbüchern zu Objekten erreichen?

Bearbeiten: Der fragliche Code (dict-basiert) ist hier . Die erste Version, in der ich versuchte, sie objektorientiert zu machen, ist hier .

    
098799 15.01.2017, 12:09
quelle

3 Antworten

7

Was können Sie beim Wechsel von Wörterbüchern zu Objekten erreichen?

Das ist eine ziemlich große Frage.

In Python ist es richtig, dass ein Objekt semantisch äquivalent zu einem Wörterbuch ist, da ein Objekt fast äquivalent zu seinem __dict__ -Attribut ist (ich werde dieses "fast" hier nicht näher beschreiben, da es weit weg vom Thema ist).

Ich sehe zwei Hauptvorteile durch die Verwendung von Klassen anstelle von Wörterbüchern: Abstraktion und Komfort.

Abstraktion

Wenn Sie sich in der Entwurfsphase befinden, insbesondere für kurze bis mittlere Programme, möchten Sie im Allgemeinen das Skelett Ihres Codes schreiben, während Sie nachdenken.

In einer Situation, in der Sie Interaktionen modellieren müssen, ist es natürlicher, in Klassen zu denken, weil es zwischen Sprechen und Programmieren liegt.

Dies erleichtert es, Ihre eigene Problematik zu verstehen. Außerdem verbessert es die Lesbarkeit Ihres Codes erheblich, weil es natürlich erscheint, selbst wenn der Leser nichts über Ihren Code weiß.

Dies bringt Ihnen Konzepte wie Vererbung und Polymorphismus, die die von OOP angebotene Abstraktion bereichern.

Komfort

Eine der vielen Stärken von Python ist das Datenmodell . Die vielen magischen Methoden und Attribute ermöglichen es Ihnen, sehr einfache Syntaxen zu verwenden. Außerdem kann es einige Operationen an Ihrer Stelle erledigen.

Hier sind einige Vergleiche zwischen imperativer und objektorientierter Programmierung in Python .

Natürlich ist alles in Python ein Objekt, also werde ich Punktanrufe ( foo.bar() ) sogar in imperativen Beispielen verwenden.

Dateien lesen

Imperativer Weg

%Vor%

Objektorientierter Weg

%Vor%

Beachten Sie, dass for line in f eine umfangreiche Verwendung des objektorientierten Datenmodells von Python ist. Stellen Sie sich den Schmerz vor, wenn diese Syntax nicht existiert (gut, versuchen Sie es einfach in C).

Leere-Test

Imperativer Weg

%Vor%

Objektorientierter Weg

%Vor%

Iteration über eine Sequenz

Imperativer Weg

%Vor%

Objektorientierter Weg

%Vor%

Aber die tatsächliche Stärke dieses Datenmodells besteht darin, dass Sie viele magische Attribute neu definieren können. Zum Beispiel können Sie komplexe Dinge vergleichbar machen, indem Sie __lt__ , __le__ usw. implementieren, wodurch das Verhalten von < , <= usw. neu definiert wird. Von nun an werden integrierte Funktionen wie min , max oder sort verstehen, wie Sie Ihre Objekte vergleichen können.

Dies gesagt, die Verwendung von bloßen Wörterbüchern kann in einer großen Vielfalt von Fällen mehr als genug sein.

Und am Ende des Tages ist OOP nur ein Paradigma, und imperative Programmierung funktioniert genauso gut.

    
Right leg 24.01.2017 16:59
quelle
3

tl; dr Die Antwort ist Polymorphismus

Klassen sind nicht inhärent besser als dicts, nur anwendbar auf verschiedene Problembereiche. Wenn Sie 3 Objekte erstellen möchten, die sich wie Dicts verhalten, verwenden Sie einfach Dicts. Also, wenn A, B und C Diktate sind und das dein Problem löst, dann bist du fertig: Diktate sind die richtige Wahl.

Wenn es sich tatsächlich um verschiedene Dinge mit unterschiedlichen Datenstrukturen und vielleicht radikal unterschiedlichen Implementierungen handelt, dann sind Diktate nicht die richtige Antwort.

In diesem Fall jedoch (und hier helfen Ihnen Klassen) bieten Klassen Polymorphismus , um Sie bei Ihrem angegebenen Problem zu unterstützen. Hier können mehrere Objekte, obwohl sie verschiedenen Klassen angehören, jeweils auf dieselbe Weise auf ihre eigene Art antworten.

Sie können also eine "use" -Methode für die Klassen A, B und C implementieren. OBJEKTE dieser Klassen reagieren nun auf diese Methode, obwohl die übrigen Implementierungen sehr unterschiedlich sind.

Dies wird am einfachsten in der Funktion __str__ der Basisklassen dargestellt.

%Vor%

Niemand wird jemals die Funktion einer Ganzzahl (dh Mathematik) mit der Funktion einer Zeichenkette verwechseln (dh Text speichern), aber beide antworten auf die gleiche Nachricht __str__ . Deshalb funktioniert Folgendes:

%Vor%

In Ihrem Fall können Sie also drei Klassen A, B und C mit sehr unterschiedlichen Implementierungen haben, aber geben Sie ihnen jeweils eine ähnliche Methode "use". Dann, wenn Sie alle ihre "Verwendung" fragen, werden sie alle auf die gleiche Weise antworten, und Sie können Ihre Verwendungsliste zusammenstellen.

Ihr Code ist voll mit langen " case " Anweisungen, hier ist eine großartige Diskussion darüber, wie Sie Polymorphie verwenden können, um sie zu entfernen:

Möglichkeiten zur Deaktivierung von Code-Wechsel

Sie sollten in der Lage sein, die Menge an Code drastisch zu reduzieren, insbesondere alle sich wiederholenden Teile, indem Sie alle der Steueranweisungen (ifs) entfernen und sie durch Senden von Nachrichten an Objekte ersetzen Lassen Sie die Objekte herausfinden, was zu tun ist. Ihre Objekte sollten Methoden wie "importieren", "exportieren" und "hinzufügen" haben.

    
RobertB 30.01.2017 18:07
quelle
0

Was ist, wenn Sie einfach jede Klasse von dict erweitern und ihr Verhalten personalisieren?

%Vor%

Ich meine ... sie werden immer noch Wörterbücher sein, werden als Wörterbücher funktionieren, aber Sie können einige eigene Methoden definieren.

Bearbeiten:

Ok ... Ich habe deinen Code gelesen und versucht, etwas OOP daraus zu machen. Nicht wirklich die beste OOP aller Zeiten, aber Sie können die Idee bekommen. Code ist sauberer, einfacher zu debuggen, einfacher zu erweitern, einfacher zu warten und so weiter ...

Hier ist der Dropbox-Ordner: Ссылка

Was denkst du?

    
Vinicius Matté Gregory 24.01.2017 16:40
quelle