OOP-Anfängerproblem

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
acidbath
User
Beiträge: 21
Registriert: Mittwoch 26. Januar 2011, 19:10

Hallo allerseits.

Ich stehe vor folgendem Problem: ich habe eine gegebene Anzahl von unterschiedlichen pdf-Dateien, deren Inhalt ich auswerten möchte.
Der prinzipielle Ablauf ist wie folgt:
- über subprocess.check_output pdftotext ausführen und den Textinhalt der Rechungs-PDF entgegennehmen
- den Textstring untersuchen und bestimmen, von welchen Händler die Rechung ausgestellt wurde
- mit diesem Wissen jetzt relevante Daten aus dem Textstring auslesen, etwa den Rechnungsbetrag
Natürlich könnte ich alles in eine einzige Routine mit tausend ifs packen, aber schön ist natürlich etwas anderes. Also dachte ich als erstes (und vermutlich falsch) an eine Klasse Rechnung, die in ihrer init-Routine die ersten zwei Schritte absolviert. Soweit so gut, problematisch wird es dann aber bei Schritt 3. Jetzt könnte ich natürlich alle weiteren Methoden mit dem Parameter des Rechnungserstellers aufrufen (etwa: invoice.return_billing_amount('Amazon') ) und in der Routine wiederum mit einer if-Abfrage verfahren, je nachdem welches Unternehmen übergeben wurde, aber der Übersicht ist das nicht dienlich, selbst wenn ich für jedes einzelne Unternehmen eine separate Prozedur aufrufe.
Alternativ hatte ich auch schon daran gedacht, vorneweg ein Dictionary anzulegen, welches die Namen an die entsprechenden Routinen bindet, als Pseudocode etwa:

Code: Alles auswählen

def return_billing_amount_amazon():
    [...]

return_billing_amount = {'Amazon': return_billing_amount_amazon}
print return_billing_amount['Amazon']()
Vermutlich liegt die Lösung in OOP, aber hier ist mir nicht klar, von welcher Seite ich das Pferd aufzäume. Eine Klasse invoice, dann wiederum Klassen für die einzelnen Händler die von invoice erben? Und die Händlererkennung als statische Methode (womit ich einen Begriff verwendet habe, den ich vermutlich nicht einmal richtig verstanden habe :D )?
Oder so:

Code: Alles auswählen

class Amazon_Invoice(object):
    [...]

class Invoice(object):
    def __init__(self):
        # Erkennung des Händlers
        [...]
        if dealer_name == 'Amazon':
            self.invoice = Amazon_Invoice( ... )
Aber dann müßte ich ja händisch alle Methoden an die Methoden von Amazon_Invoice binden?!

Mein Ziel soll sein:

Code: Alles auswählen

[...]
invoice = Invoice('Rechnung.pdf')
print invoice.return_billing_amount()
Ein dezenter Stoß in die richtige Richtung wäre klasse!

Dank und Gruß,
Daniel
BlackJack

@acidbath: Der Ansatz mit dem Wörterbuch zum Abbilden von Händer auf weiterverarbeitende Funktion war doch nicht schlecht. Bei Klassen wäre das so ähnlich, nur dass man dann halt auf die konkrete Klasse abbilden würde. Eine Basisklasse `Invoice` die in ihrer `__init__()` erst entscheidet um welchen Händler es sich handelt, macht jedenfalls keinen Sinn.

Ob Klassen überhaupt Sinn machen hängt davon ab welche Daten und Funktionen da nun genau in einer Klasse zusammengeführt werden sollen.
acidbath
User
Beiträge: 21
Registriert: Mittwoch 26. Januar 2011, 19:10

Danke für Deine schnelle Antwort, BlackJack.
BlackJack hat geschrieben:@acidbath: Der Ansatz mit dem Wörterbuch zum Abbilden von Händer auf weiterverarbeitende Funktion war doch nicht schlecht. Bei Klassen wäre das so ähnlich, nur dass man dann halt auf die konkrete Klasse abbilden würde. Eine Basisklasse `Invoice` die in ihrer `__init__()` erst entscheidet um welchen Händler es sich handelt, macht jedenfalls keinen Sinn.
Nur damit ich's richtig verstehe: Du würdest also in meinem Fall die ersten 2 Schritte 'extern' außerhalb irgendeiner Klassendefinition abarbeiten und sobald Du sowohl den Rechnungsstring als auch den Händlerstring hast, auf die Dictionaryvariante zurückgreifen, also etwa:

Code: Alles auswählen

invoice_text_content = [...]
dealer_id = [...]
dealer_invoice_classes = ['Amazon': Amazon_Invoice, 'Reichelt': Reichelt_Invoice]
invoice = dealer_invoice_classes[dealer_id](invoice_text_content)
BlackJack

@acidbath: Ja so in etwa. Falls `Amazon_Invoice` & Co Klassen sein sollten, dann übrigens konventionell ohne den Unterstrich.

Wobei wenn es Sinn macht, kann das extrahieren natürlich auch in irgendeiner Klasse passieren.
acidbath
User
Beiträge: 21
Registriert: Mittwoch 26. Januar 2011, 19:10

Moinsen.
BlackJack hat geschrieben:Ja so in etwa. Falls `Amazon_Invoice` & Co Klassen sein sollten, dann übrigens konventionell ohne den Unterstrich.
Oh ja, stimmt, da war doch was... :D
BlackJack hat geschrieben:Wobei wenn es Sinn macht, kann das extrahieren natürlich auch in irgendeiner Klasse passieren.
Klar, aber zumindest in meinem Fall wäre das wohl wirklich mit Kanonen auf Spatzen schießen. Zumal das hier im Forum ja auch der Konsens zu sein scheint: OOP nur da wo's Sinn ergibt und nicht allein der OOP wegen.
Antworten