importieren von Objects in "list"

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
chris1887
User
Beiträge: 5
Registriert: Donnerstag 30. April 2015, 09:12

Hallo zusammen,

ich bin seit vorgestern dabei mir die Sprache Python anzueignen, daher bitte ich um Verständnis falls der ein oder andere Ausdruck noch nicht dem "Regelwerk" entspricht...

Info:

Ich sitze an der Aufgabe ein kleines "Auftragsprogramm" zu schreiben.
Dies soll die einen Auftrag erfassen, inkl. Sachbearbeiter und Kunde. Es gibt nur einen Auftrag/Sachbearbeiter/Kunde.
Jedoch kann ein Auftrag mehrere Posten haben.(ein Posten besteht aus der variablen: "menge und produkt". Wobei "produkt" ein andere Klasse ist. Die Klasse Produkt enthält. "preis und name" des Produktes.)

Die erste Version des Programmes entheilt statische variablen für posten. Mein Constructor für die Klasse Auftrag sah in dem Fall so aus:

def __init__(self, sachbearbeiter, kunde, posten1=None, posten2=None):
'''
Constructor
'''

self.__posten1 = posten
self.__posten2= posten
self.__sachbearbeiter = sachbearbeiter
self.__kunde = kunde


Jetzt hatte ich das Problem das ich die Preise usw. nicht berechnen konnte wenn ein Posten fehlte. Außerdem war das Programm zu statisch, was wenn man mehr als 2 Posten erfassen möchte.
Darum dachte ich mir das ich eine Liste erstelle..
der neue Konstruktor sieht wie folgt aus:

def __init__(self, sachbearbeiter, kunde):
'''
Constructor
'''

self.posten = []
self.__sachbearbeiter = sachbearbeiter
self.__kunde = kunde


Meine Idee war wenn ich einen posten erstelle, das dieser dann mit folgender Methode in die Liste Posten geshrieben wird:


def addPosten(self, neuerPosten):
self.posten.append(neuerPosten)

Wenn ich mir dann die Liste Posten ausgeben lassen möchte (mit folgender Methode):

def getPosten(self):
return self.posten

bekomem ich immer nur den Speicherort übergeben. Ich möchte aber gerne den Inhalt sehen bzw. auch weiter verarbeiten.

Meine beiden anderen Konstruktoren der Klasse (Produkt und Posten) sehen wie folgt aus:

Produkt:

class Produkt(object):

def __init__(self, preis, name):
self.__preis = preis

self.__name = name


jeweils mit Get und Set Methoden für preis und name.


Posten (der Übergabe Parameter produkt, bezieht sich auf ein Object der Klasse Produkt):


def __init__(self, menge, produkt):

self.__produkt = produkt
self.__menge = menge


auch mit Get und Set Methoden.



Ich verstehe nun nicht wie ich das Object "posten" in die Liste hinzufüge und wie ich mir diese ausgeben lassen kann(sprich mit den variablen).
Außerdem würde ich gerne mit dem Eintrag in der Liste arbeiten z.B. einen Preis berechnen, hier fehlt mir das Verständnis wie ich auf die Parameter zugreifen kann.
Hinzu kommt das auch neue posten in die Liste geschrieben werden sollten ohne den alten zu überschreiben.



Ich hoffe ich habe das einigermaßen richtig formuliert.


Vielen Dank für das mitgrübeln.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo chris1887,
hier im Forum gibt es Tags für Python-Code

Code: Alles auswählen

, damit werden auch Einrückungen korrekt angezeigt, die ja fürs Verständnis essentiell sind. Es gibt ein paar [url=https://www.python.org/dev/peps/pep-0008/]Konventionen[/url], an die Du Dich am besten von Anfang an hältst. Deshalb sollte es "add_posten" oder "neuer_posten" heißen. Namen mit doppelten Unterstrichen sind für einen ganz speziellen Zweck reserviert, in Deinem Fall gehören die Attribute aber zur öffentlichen Schnittstelle, sollten also gar keinen Unterstrich haben. __init__ ist keine Constructor, sondern ein Initialisator. getPosten ist überflüssig, da man auch direkt obj.posten schreiben kann, und natürlich bekommst Du eine Referenz auf die Liste, weil alles Objekte sind und man nur Referenzen auf diese Objekte weitergibt. Zum Verarbeiten von Listen gibt es for-Schleifen, die beim Lernen von Python eigentlich vor Klassen auftauchen sollten. Auch in Produkt und Posten sind die doppelten Unterstriche falsch und Get und Set unnötig.
chris1887
User
Beiträge: 5
Registriert: Donnerstag 30. April 2015, 09:12

Hallo,

danke für die schnelle Antwort.

Die beiden unterstriche habe ich gesetzt, damit die Sichtbarkeit "private" ist. Da ich die Objekte nur durch entsprechende Methoden bearbeiten möchte.
Beeinträchtigt dies die Funktion des Programms? Durch die bereit gestellten Get und Set Methoden sollte die funktionalität eigentlich gewährleistet sein?

Bis jetzt habe ich mit der for-schleife nur eine Aufgabe bearebeitet im das "kleine" Ein mal Eins wieder zu geben.
Inwiefern könnte man mit der for-Schleife eine Liste bearbeiten?
Dies leuchtet mir derzeit noch nicht ein.

Weil mit der for-Schleife würde ich ja die komplette Liste bzw. nur einen festgelegten Teil der Liste durchlaufen. Nur wie lege ich fest das genau das Attribut von dem Objekt zur Verarbeitung benötige.
wäre das in etwa so?

Code: Alles auswählen


for gesuchtes_attribut in liste():
und anschließend könnte ich eine Methode einsetzen um das Attribut zu verarbeiten?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@chris1887: Deine Attribute sind ja nicht "privat", weil man per set und get darauf zugreifen kann, also ist es schonmal logisch falsch. Die Begriffe "private" oder "protected" gibt es in Python übrigens nicht, und die Unterstriche sind nur Hinweise für den Programmierer. Daher ist "privat" bei Dir falsch. Die Funktion des Programms ist beeinträchtigt, weil es viel komplizierter ist, das Programm zu schreiben, zu lesen und zu verstehen, und das sind die drei für Dich wichtigsten Eigenschaften, die jedes Programm haben sollte. Wenn Du das Konzept einer for-Schleife noch nicht verstanden hast, solltest Du nochmal zu den Grundlagen von Python zurückgehen, bevor Du mit Klassen weitermachst; eine Übung mit Schleifen gemacht zu haben, reicht bei weitem nicht aus.
chris1887
User
Beiträge: 5
Registriert: Donnerstag 30. April 2015, 09:12

Okay,

dann werd ich nochmal zurückrudern und mir die for-Schleife anschauen.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wo hast Du denn die Info her, dass Methoden ``private`` sein sollen? Vergiss dieses Buch, Tutorial oder diesen Kurs einfach ganz schnell - deine Quelle(n) haben sich damit selbst disqualifiziert!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
chris1887
User
Beiträge: 5
Registriert: Donnerstag 30. April 2015, 09:12

Hallo,
also nicht die Methoden sind "private" sondern die Attribute.

Also meine Methoden sind nicht als pirvate gekennzeichnet, jedoch ggf. die Attribute in der Methode.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

chris1887 hat geschrieben:also nicht die Methoden sind "private" sondern die Attribute.
Um die Python-Dokumentation zu zitieren: "“Private” instance variables that cannot be accessed except from inside an object don’t exist in Python.".

Wenn du Attribute oder Methoden haben möchtest die als nichtöffentlich betrachtet werden sollen, dann kennzeichne sie mit einem führenden Unterstrich. Das ist der Hinweis für andere Entwickler, dass sie die Finger davon lassen sollten - oder zumindest auf eigenes Risiko damit arbeiten.
gerpark
User
Beiträge: 7
Registriert: Montag 19. Januar 2015, 20:58

Hallo chris1887,

Die Liste mit den 'posten' und das einzelne Listenelement
wird ebenfalls als 'posten' bezeichnet, das ist vielleicht etwas verwirrend.
(Bei Auftragsposition/en würden sich z.B. Plural vom Singular unterscheiden).

Ansonsten ist der Ansatz aber richtig, du holst dir zuerst die Liste aus dem Auftragsobjekt.
Danach holst Du dir mit der 'for-schleife' die einzelnen Listenelemente.
Im dritten Schritt kannst Du dann die einzelne Elemente bearbeiten, wie z.B das Produkt ausgeben
oder Preise zusammenzählen etc.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

chris1887 hat geschrieben:also nicht die Methoden sind "private" sondern die Attribute.
Im Gegensatz zu Sprachen wie Java sind Mathoden einfach Funktionsattribute eines Objektes, die werden genauso behandelt wie jedes andere Attribut auch.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
chris1887
User
Beiträge: 5
Registriert: Donnerstag 30. April 2015, 09:12

Hallo,

danke für die zahlreichen Antworten!

ich werde die Sichtbarkeit anpassen und anschließend versuchen das Problem der Ausgabe zu beheben.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

gerpark hat geschrieben: Ansonsten ist der Ansatz aber richtig, du holst dir zuerst die Liste aus dem Auftragsobjekt.
Darüber kann man sich schon streiten! Evtl. wäre es sinnvoller, einen Iterator über die Posten anzubieten, denn dann wäre die interne Datenstruktur (aktuell eben eine Liste) nach außen gekapselt und nur das Protokoll definiert, was dem Law of Demeter besser entspräche.

(Oder der Auftrag implementiert selber das Iterator-Protokoll...)
chris1887 hat geschrieben: ich werde die Sichtbarkeit anpassen und anschließend versuchen das Problem der Ausgabe zu beheben.
Um es noch einmal zu wiederholen: Es gibt keine "echte" Sichtbarkeit in Python! /me hatte Dir sogar die Python Doku zitiert!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten