OOP für Dummy's

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.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

pütone hat geschrieben:Das wäre sicher hilfreich, denn es kommen ja doch öfter Fragen nach gedruckter deutschsprachiger Literatur. Bis es soweit ist, hilft vielleicht dem ein oder anderen dieser Link: http://www.way2python.de/pythonbuch/buecher.html
Ja, wir sollten echt mal eine Wiki-Seite anlegen. So eine war zwar im alten Wiki, aber diesmal müssten wir es klarer formulieren, so dass der Einsteiger schneller sieht was empfehlenswert ist und was nicht.
pütone hat geschrieben:Dir würde z.B. gerade das von mir oben angepriesene Buch von M. Weigend vermutlich weniger gefallen, weil er konsequent von "Methoden" und "Attributen" spricht, statt alles "Attribute" zu nennen (da wäre Lutz/Ascher dann vorzuziehen). Auch verwendet Weigend konsequent file() statt open(), kennt noch keine Dekoratoren und behauptet, man könne Attribute (= Datenattribute) mittels __mydata sicher privatisieren - was so ja auch nicht stimmt.
Das ist schon mal eine wertvolle Beobachtung - du könntest auch überlegen, das an den Verlag zu schicken, damit das Buch besser wird. Es ist ja durchaus keine Schade mal Fehler/Ungenauigkeiten zu haben, sofern man es dann besser macht :)

P.S.: Ich verwende in meiner Sturheit auch öfter ``file`` als ``open`` ;)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@Leonidas: Da wird Dich Python 3.0 von "heilen":

Code: Alles auswählen

>>> file
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'file' is not defined
:-)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

BlackJack hat geschrieben:@Leonidas: Da wird Dich Python 3.0 von "heilen":

Code: Alles auswählen

>>> file
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'file' is not defined
Hallo!

:-)
Das ist nicht lustig! ``file`` war für mich immer logischer als ``open``. Denn öffnen kann ich viel! Aber mit ``list`` bekomme ich eine Liste zurück. Mit ``dict`` bekomme ich ein Dictionary. Und mit ``file`` bekomme ich ein File.

``open`` war für mich immer schon "unlogisch". Und ich freute mich sehr, als ich herausfand, dass man mit ``file`` ein File-Objekt erzeugen kann.

Das Abschaffen von ``file`` ist wieder so ein Beispiel dafür, das mich glauben lässt, dass Python 3.0 nicht wirklich gut durchdacht sein wird. Es wäre wohl eher eine logische Konsequenz gewesen, ``open`` zu lassen und ``file`` zu forcieren. Aber was soll's. :roll:

Ich bin nicht in die Entwicklung involviert und die anderen Spinner (sorry) werden erst drauf kommen, wenn sie ein zweites .NET geschaffen haben.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

BlackJack hat geschrieben:@Leonidas: Da wird Dich Python 3.0 von "heilen"
Wovon leitet man dann ab? Oder muss man dann das Interface der ABCs aus PEP 3116 implementieren?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Also ich finde so eine Fabrikfunktion praktischer als `io` importieren zu müssen und da die richtige Klasse zu "suchen". Wenn man damit anfängt, dann ist es nicht mehr weit bis Java. ;-)

Es gibt in 3.0 nicht mehr ein `file` für alles, sondern verschiedene Klassen für Binärdaten und Text mit eingebauter Konvertierung von/nach Unicode. Ein ``open('text.txt')`` liefert eine zum lesen geöffnete Textdatei mit UTF-8-Kodierung.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Gerold hat geschrieben:Das ist nicht lustig! ``file`` war für mich immer logischer als ``open``. Denn öffnen kann ich viel! Aber mit ``list`` bekomme ich eine Liste zurück. Mit ``dict`` bekomme ich ein Dictionary. Und mit ``file`` bekomme ich ein File.
Da möchte ich dir uneingeschränkt zustimmen. Mir gefällt "file" auch viel besser als "open" - trotzdem benutze ich "open", weil es gemäß offizieller Doku eben so empfohlen wird. Im Hinblick auf Py 3000 sollte man sich eben dran gewöhnen.

Aber gefallen tut mir das nicht.
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

Es Läuft
Leute ich habs 4 Tage und das letzte Tutorial hats gebracht
so als nächstes were ich tkinter dann rauswerfen und alles in wxPython fummeln
es gibt da in der DEMO auswahl für Kalender und Filesystem
das wird sicherlich toll für mich

DANKE an die FREAKS und OOP ASSE

programme
http://www.euroschall.de/boerse_V1-3.rar

screenshot
Bild
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

BITTE BITTE noch ein TIP

Wie schaff ich es das bei Jedem internet Rückgabewert das gleich angezeigt wird
Beim Einlesen liest das Programm alle Werte erst ein und bringt dann alles was Gemacht wurde zur ausgabe
sollte aber Ständig das Ausgeben was es zur Zeit macht,

Code: Alles auswählen

def Ausgabe(text):
        textfenster.insert(END,'\n ' + text)
        textfenster.see(END)

Ausgabe('\nerstelle csv Dateien')
        while x < len(symbol_liste):
            url=("http://ichart.yahoo.com/table.csv?s=%s&a=%s&b=%s&c=%s&d=%s&e=%s&f=%s&g=d&ignore=.csv" %(symbol_liste[x],Monatvon,Tagvon,Jahrvon,Monatbis,Tagbis,Jahrbis))
            Ausgabe(url)
            req = urllib.urlopen(url)
           
            f = file("%stecdax\\%s.csv"%(pfad,symbol_liste[x]), 'w')
            f.write(req.read())
            f.close()
            req.close()
            Ausgabe(symbol_liste[x]+' erledigt')
            x=x+1
        Ausgabe('\nDateien aus Internet erstellt')
        tkMessageBox.showinfo('Info',"TecDax eingelesen")

###main
textfenster = ScrolledText(root,background='white',font=('Verdana',10,'bold'))
textfenster.pack(expand=NO)

lunar

gerold hat geschrieben:``file`` war für mich immer logischer als ``open``.
Siehst du, mir geht es genau umgekehrt, denn ...
Denn öffnen kann ich viel! Aber mit ``list`` bekomme ich eine Liste zurück. Mit ``dict`` bekomme ich ein Dictionary. Und mit ``file`` bekomme ich ein File.
... das, was ``file`` zurückgibt, ist in meinen Augen kein Dateiobjekt, da es lediglich den Inhalt wiederspiegelt. Ich erhalte über ``file``keinerlei Zugriff auf die Metainformationen einer Datei (Größe, Rechte, Eigentümer, etc.), obwohl all diese Dinge klar mit einer Datei verbunden sind. Mehr noch, der Name ``file`` verbirgt den Zweck des zurückgegebenen Objekts.

``open`` dagegen drückt klar aus, dass es in diesem Fall nicht um Metainformationen geht, sondern allein darum, die Datei zum Lesen oder Schreiben des Inhalts zu öffnen. Hier ist der thematische Zusammenhang imho wesentlich klarer.
Das Abschaffen von ``file`` ist wieder so ein Beispiel dafür, das mich glauben lässt, dass Python 3.0 nicht wirklich gut durchdacht sein wird.
Es ist durchdacht, eines der beiden Duplikate zu entfernen. Welches das letztendlich ist, kann einem doch eigentlich egal sein ;) Ich halte ``file`` für die überflüssige Variante... wenn du das anders siehst, bitte:``file = open`` steht dir ja frei.
Es wäre wohl eher eine logische Konsequenz gewesen, ``open`` zu lassen und ``file`` zu forcieren. Aber was soll's. :roll:
Glücklicherweise sind wir nicht in der Mathematik, so dass niemand gezwungen ist, in deiner subjektiven Meinung tatsächlich eine Logik zu erkennen.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

lunar hat geschrieben:
Denn öffnen kann ich viel! Aber mit ``list`` bekomme ich eine Liste zurück. Mit ``dict`` bekomme ich ein Dictionary. Und mit ``file`` bekomme ich ein File.
... das, was ``file`` zurückgibt, ist in meinen Augen kein Dateiobjekt, da es lediglich den Inhalt wiederspiegelt. Ich erhalte über ``file``keinerlei Zugriff auf die Metainformationen einer Datei (Größe, Rechte, Eigentümer, etc.)
Hallo lunar!

Für die Metainformationen einer Datei wäre dann ``fileinfo`` zuständig. ;-)

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
pot
User
Beiträge: 55
Registriert: Sonntag 4. März 2007, 00:57
Wohnort: Frauenfeld, CH

Leonidas hat geschrieben:Ja, das Kapitel gibt einen guten Überblick darüber, wie man es falsch macht. Schade dass die dahinter nicht geschrieben haben "Haha, war alles nur Spaß, hier wie man das in Python machen würde: ...".
Das steht dann auch im nächsten Kapitel:

http://www.galileocomputing.de/openbook ... .htm#t2t32

Grüsse
Pot
BlackJack

@pot: Ich glaube Du hast es nicht ganz verstanden: Den Link, den Du da angibst, da fängt es ja gerade an schrecklich zu werden! Ab da wird gezeigt wie man OOP in Python *nicht* machen sollte.
pot
User
Beiträge: 55
Registriert: Sonntag 4. März 2007, 00:57
Wohnort: Frauenfeld, CH

Ich hab' es mir zwar nicht wirklich durchgelesen, bin jedoch nicht so erfahren das zu bestätigen. Was ist denn daran so falsch?

Grüsse
Pot
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

pot hat geschrieben:Ich hab' es mir zwar nicht wirklich durchgelesen, bin jedoch nicht so erfahren das zu bestätigen. Was ist denn daran so falsch?
Müssen wir diese Diskussion in jedem Thread wiederholen? Schau doch einfach nach was bereits gesagt wurde.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

gerold hat geschrieben:
lunar hat geschrieben:
Denn öffnen kann ich viel! Aber mit ``list`` bekomme ich eine Liste zurück. Mit ``dict`` bekomme ich ein Dictionary. Und mit ``file`` bekomme ich ein File.
... das, was ``file`` zurückgibt, ist in meinen Augen kein Dateiobjekt, da es lediglich den Inhalt wiederspiegelt. Ich erhalte über ``file``keinerlei Zugriff auf die Metainformationen einer Datei (Größe, Rechte, Eigentümer, etc.)
Hallo lunar!

Für die Metainformationen einer Datei wäre dann ``fileinfo`` zuständig. ;-)
Dann aber zwecks Konsistenz bitte auch ``fileopen`` oder ``FileStream`` anstatt ``file``... und dann sind wir vollends bei .NET angekommen ;)
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

MECKER


ICH weis Ja nicht wie ihr das Hier Handhabt
Ich hatte einen THread mit OOP eröffnet und nun wird über SCHLANGE 3.0 Diskutiert
ist das hier so Sitte völlig abseits vom Thread_THEMA
EIN NEULING
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Geh. Weg.
BlackJack

@pot: Kapitel 12.1.2: `__del__()` sollte man entweder gar nicht erwähnen, oder in einer Warnung, dass man es nicht verwenden soll. Der Text behandelt es aber wie einen Destruktor in C++, ohne jegliche Warnung, dass die ganzen Probleme, die man sich damit einhandeln kann, und die Garantien, die die Sprache (nicht) macht, diese Methode letztendlich nutzlos bis gefährlich machen.

Die Erklärung `Destruktoren werden aber häufig benötigt, um beispielsweise bestehende Netzwerkverbindungen sauber zu trennen, den Programmablauf zu dokumentieren oder Fehler zu finden.` ist jedenfalls falsch. Wenn man eine Ressource sauber abräumen will, kann man sich nicht aus `__del__()` verlassen, da weder garantiert wird, wann die Methode aufgerufen wird, noch ob sie *überhaupt* jemals aufgerufen wird. Den Programmablauf dokumentieren, ich nehme mal an hier ist protokollieren der Art "Objekt xy wurde gerade zerstört" gemeint, geht mit `__del__()` folglich auch nicht. Und eine Methode zur Fehlersuche zu verwenden, die durch ihre blosse Existenz schon drastischen Einfluss auf das Verhalten des Programms bezüglich der Speicherfreigabe haben kann, halte ich auch für keine gute Idee.

Die Erklärung von `__init__()` als Konstruktor ist technisch gesehen falsch. Der echte Konstruktor heisst in Python `__new__()`.

Das Ende des Kapitels lässt den Horror ahnen, der im Nächten folgt: `Allerdings ist es immer noch möglich, außerhalb der Klasse auf die Attribute direkt zuzugreifen und diese zu verändern, […]` und `Auch die Zuweisung von Werten ungültiger Datentypen wird noch nicht verhindert.`

Damit verlassen die Autoren die Welt der Python-Programmierung und betreten die Abgründe der "discipline-and-bondage"-Sprachen. Wer statische Typisierung und Zugriffsschutz mag, soll doch bitte nicht in Python programmieren und erst recht keine Bücher darüber schreiben.

In Kapitel 12.1.3 werden dann auch erst einmal alle Attribute mittels doppelter führender Unterstriche "private" gemacht, um gleich darauf einen trivialen Getter ein zu führen. Bezeichnung dafür ist `private members`. Irgendwie nicht die übliche Python-Nomenklatur ─ warum können die nicht bei "Attribut" oder "attribute" bleiben? Das die beiden Unterstriche dazu gedacht sind, Namenskollisionen bei Mehrfachvererbung zu vermeiden, wird weder hier, noch später im Abschnitt über Vererbung erwähnt.

Danach folgt ein Setter, der das Argument mit `type()` auf `float` oder `int` prüft. Was a) dem "duck typing" zuwieder läuft und b) selbst für eine explizite Prüfung schlechter Stil ist, weil damit völlig unnötigerweise auch alle Objekte ausgeschlossen werden, deren Typ von `int` oder `float` abgeleitet wurde.

Getter und Setter werden in 12.1.4 durch Properties ersetzt, wobei diese im Text als `Managed Attributes` bezeichnet werden.

Das Beispiel für `Statische Member` ist wieder komplett an der Realität vorbei, weil man `__del__()` so eben nicht zuverlässig verwenden kann. Man kann damit sehen wieviele Exemplare von `Konto` gerade existieren, sieht aber nicht, welche davon wirklich von der Bank verwendet werden oder welche aus verschiedenen anderen Gründen noch im Speicher herumhängen.

Statische Methoden werden als relativ Nutzlos hingestellt, dabei werden sie ─ und Klassenmethoden, die gar nicht erwähnt werden ─ häufig für alternative Konstruktoren verwenden.

Wenn wir schon "private" Attribute haben und auf Typen prüfen, darf in 12.3.1 `__slots__` als Mittel zum verhindern vom dynamischen hinzufügen von Attributen nicht fehlen. Der eigentliche Zweck, dass Exemplare mit "slots" weniger Speicherplatz benötigen, wird erst an zweiter Stelle erwähnt.

Und gerade wo man denkt es kann nicht schlimmer werden, kommt am Ende, unter der Überschrift `Objektphilosophie`, noch ein Beispiel wie konsequente Objektorientierung es erleichtert wiederverwendbaren Code zu schreiben, das so schlecht ist, dass es einem die Sprache verschlägt:

Code: Alles auswählen

class ListeMitDurchschnitt(list): 
    def durchschnitt(self): 
        summe, i = 0.0, 0 
        for e in self: 
            if type(e) in (int, float): 
                summe += e 
                i += 1 
        return summe / i
IMHO ein klarer Fall wo eine generische Funktion viel flexibler ist, als eine Liste um diese Methode erweitert. Folgende Funktion funktioniert mit jedem "iterable" und allem was sich addieren und durch eine ganze Zahl teilen lässt. Zum Beispiel auch mit `decimal.Decimal`- oder `gmpy.mpq`-Objekten.

Code: Alles auswählen

def average(iterable, start_value=0):
    total = start_value
    i = None
    for i, value in enumerate(iterable):
        total += value
    if i is None:
        raise ValueError('iterable must contain at least one argument.')
    return total / (i + 1)
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

Ein Buch(Programm) ist nur so gut wie der Autor(Programmierer)

und selbst BlackJack lernt immer noch was dazu (denk ich jedenfals)

es gibt immer einer der es besser weis
und hinterher ist man sowieso schlauer

ALBERT EINSTEIN
Holzhauen ist so beliebt weil man das ergebniss gleich sieht!
Granino
User
Beiträge: 19
Registriert: Freitag 10. August 2007, 15:40

Die Hoffnung stirbt zuletzt sagte mein OOP Prof man kann auch noch mit 50
Und was sagt Dein Prof zur Obergrenze?
Vielleicht verstehe ich dann, woher meine Problleme stammen.
Gruß Granino
Antworten