Probleme mit der Anleitung

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.
template
User
Beiträge: 29
Registriert: Mittwoch 21. November 2007, 09:44

Probleme mit der Anleitung

Beitragvon template » Mittwoch 21. November 2007, 10:01

Hallo,

ich komme aus der C/C++ Ecke und habe bis jetzt Hauptsächlich native Windows Anwendungen Programmiert. Auch für viele Utilites habe ich bis jetzt immer extra eine Anwendung geschrieben. Ich habe es auch teilweise mit Batch und Shell Script Programmierung versucht, aber das war mir im Endeffekt immer nicht Leistungsstark genug. Nachdem ich über Python nur gutes gehört habe, dachte ich es wäre eigentlich das perfekte Werkzeug für meine Alltagstätigkeiten und deshalb wollte ich mich mal einarbeiten. Nun habe ich aber, wie man sich denken kann auch schon ein kleines Problem;)

Es dreht sich um das Handbuch das bei Python mitgeliefert wird. Genauer gesagt um die Beschreibung der Standardbibliothek. Vielleicht lese ich es nur falsch aber mein erster Eindruck ist mehr als Fragwürdig. Konkret habe ich mir jetzt die Sektion über xml.minidom angeschaut. Dort viel mir allerdings auf das die Anleitung stellenweise sehr mager ist. Es steht bei den meisten Methoden überhaupt nicht dabei, wie auf eine Fehlersituation reagiert wird, z.b. welche Exceptions geworfen werden. Auch ist der Rückgabewert wohl meist überhaupt nicht erklärt, sprich von welchem Typ ist das Objekt das zurück gegeben wird und können auch besondere Objekte zurückgegeben werden, wie z.B. welche vom Typ NoneType. Gibt es vielleicht noch eine bessere Anleitung? Mir ist klar, das die Anleitung nicht unbedingt geeignet ist eine Sprache zu lernen, deswegen sehe ich Sie auch hauptsächlich als Referenz an, aber gerade von solch einer erwarte ich das Sie vollständig ist.

Vielen dank im voraus
template
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Mittwoch 21. November 2007, 10:49

Hallo template, willkommen im Forum,

Da Python nicht erfordert, dass die möglicherweise geworfenen Exceptions vorher deklariert werden, ist es unmöglich zu sagen, welche Exceptions nun geworfen werden können.

Die Rückgabewerte können ebenfalls alles mögliche sein, daher ist es oft hilfreicht, wenn du Code-Schnippsel einfach im Interpreter testest ob sie das tun was du willst.

P.S.: `None` ist kein spezielles Objekt. Es ist (fast) wie jedes andere außer dass es nur als Singleton vorliegt, aber das braucht dich in der Regel nicht zu kümmern.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
BlackJack

Beitragvon BlackJack » Mittwoch 21. November 2007, 10:58

Einige Ecken der Doku zur Bibliothek sind in der Tat nicht so toll. Beim Beispiel `xml.minidom` denke ich sollte man die DOM-Spezifikation kennen, die API ist ja standardisiert und die `minidom`-Autoren hatten sicher keine Lust das alles nochmal zu beschreiben. `ElementTree` oder `lxml` sind sowieso schöner zum arbeiten mit XML. :-)

Was die Rückgabetypen und Ausnahmen angeht: Das ist in Python halt manchmal ein wenig schwammig. Es geht beim "duck typing" nicht um die Typen sondern um das Verhalten von Objekten. Rückgabetypen, und auch Argumenttypen, werden deshalb auch gerne mal informell beschrieben, wie "ein Objekt, dass eine `read()`-Methode besitzt" oder "ein iterable über Tupel der Form (Name, Nachname)".
template
User
Beiträge: 29
Registriert: Mittwoch 21. November 2007, 09:44

Beitragvon template » Donnerstag 22. November 2007, 09:04

Ja ich gebe zu, das ist in einer nicht strikt typisierten Sprache alles gar nicht so einfach;) Aber es wäre zumindest interessant wie auf bestimmte Situationen reagiert wird. Was ist z.B. wenn eine Regular Expression nicht Matcht. Bekomme ich dann ein None als Ergebnis zurück oder wird doch ne Exception geworfen? Sowas wäre schon irgendwie gut zu wissen.
BlackJack

Beitragvon BlackJack » Donnerstag 22. November 2007, 10:13

Da gibt's ein `None`, das kann man aber auch schnell mal interaktiv ausprobieren.
template
User
Beiträge: 29
Registriert: Mittwoch 21. November 2007, 09:44

Beitragvon template » Donnerstag 22. November 2007, 12:42

Naja zum ausprobieren muss man ja eventuell erst einmal ein komplexeres Zenario aufbauen. Auserdem finde ich ausprobieren alles andere als den weisheit letzer Schluss.

Jedes Modul sollte eine wohldefinierte Schnittstelle nach ausen hin haben. Die Schnittstelle durch testen zu erraten halte ich nicht für sinnvoll, denn man kann auch schnell ein aktuelles implementationsspezifikum für einen Teil der Schnittstelle halten und sich darauf verlassen.

Es könnte ja auch einfach ein implementierungs Fehler sein das Sie sich momentan so verhält. Vielleicht war das ja vom Erfinder so ja gar nicht gedacht.

Oder vielleicht ergibt sich das aktuelle verhalten auch nur aus dem momentan verwendeten Algorithmus. Nehmen wir als Beispiel eine sortierfunktion, die nicht angibt ob Sie stabil sortiert oder nicht. Jetzt probiere ich es aus und es ist stabil. Dann wird die Sortierfunktion irgendwann so verändert das sie statt einem Bubble Sort einen Quick Sort verwendet weil er einfach wesentlich performanter ist und aus ist es mit der stabilität des Sortieralgorythmuses.

Lange rede, kurzer sinn ich verlasse mich lieber Spezifikationen statt auf Implementationen.
BlackJack

Beitragvon BlackJack » Donnerstag 22. November 2007, 13:53

Dann wirst Du wohl mit Python ein Problem bekommen. :-)
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 22. November 2007, 14:05

template hat geschrieben:Lange rede, kurzer sinn ich verlasse mich lieber Spezifikationen statt auf Implementationen.

Wenn du eine Implementation hast, die fehlerhaft ist, dann hilft dir die beste Spezifikation nicht weiter. Letztendlich musst du dich immer nach der Implementation richten.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
template
User
Beiträge: 29
Registriert: Mittwoch 21. November 2007, 09:44

Beitragvon template » Donnerstag 22. November 2007, 15:54

Wenn du eine Implementation hast, die fehlerhaft ist, dann hilft dir die beste Spezifikation nicht weiter. Letztendlich musst du dich immer nach der Implementation richten.


Da hast du natürlich recht, aber ich weiß das die Implemenation falsch ist und kann dementsprechend reagieren, z.B. den Author anschreiben damit der Fehler behoben wird und vielleicht sogar an Ort und stelle geziehlt darauf reagieren das ich es eventuell mit dieser Fehlerhaften implementation zu tun habe.

Ein Beispiel aus C. Nehmen wir folgendes Code Fragment:

Code: Alles auswählen

int i = 1;
i = (i++) + (i++);


Welchen Wert hat i nach diesem Code Fragment? Sagen wir mal ich probiere das jetzt einfach mal aus und es kommt 3 raus und dann weis ich das ja. Dann installiere ich die neue Version meines Kompilers und auf einmal kommt 2 raus. Dann beschwere ich mich beim Compilerhersteller, das das nicht mehr funktioniert. Der verweist mich nun auf die ANSI C Spezifikation aus der hervor geht, das nicht definiert ist was i nach diesem Code Fragment für einen Wert hat. Sprich laut spezifikation ist das der Richtige code um eine "Zufallswert" zu erzeugen;) Also kann ich mich auch nicht beschweren.
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Beitragvon poker » Donnerstag 22. November 2007, 15:55

Leonidas hat geschrieben:Da Python nicht erfordert, dass die möglicherweise geworfenen Exceptions vorher deklariert werden, ist es unmöglich zu sagen, welche Exceptions nun geworfen werden können.
Du meinst das die Exception dynamische *definiert* wird!?

Code: Alles auswählen

class AntiPattern(object):
    class MyExcept(Exception): pass
    def __init__(self): pass


Jo, das machen nur irrsinnige *%&/§"! (Wobei man trotzdem an die Exception zum catchen über `AntiPattern.MyExcept` rankommen würde.iiiiiiiiiieeeeeehhhh)!!

Fakt ist, das deine Aussage in Real World absolut nicht korrekt ist. Die Exceptions stehen *immer* fest! Und da sie es tun kann man das auch gleich im docstring vermerken wann sie geworfen werden. Und die 2% die sie stark dynamisch oder nested in Klassen definieren sind...irrsinnig...

Leonidas hat geschrieben:Die Rückgabewerte können ebenfalls alles mögliche sein, daher ist es oft hilfreicht, wenn du Code-Schnippsel einfach im Interpreter testest ob sie das tun was du willst.
Nein, auch hier ist "alles mögliche" ein wenig zu Allgemein gefasst (Auch wenn du insofern recht hast, das es speziele Ausnahmen gibt, die aber seltener sind und nicht die Regel darstellen).

Es ist viel mehr so wie BlackJack sagt, das man es mit Objekten zu tun hat die ein klar spezifiziertes verhalten haben (Auch wenn es nur eine read() methode ist, die das Objekt hat ;). Sie sind alle informell beschreibbar.
Also kann man das auch in den docstrings angeben ;) Wenn `X` ein Objekt ist das itterierbar sein muss (und sonst nichts fordert), kann man doch einfach in der parameterbeschreibung schreiben "``X``: iterable".

Wenn `X` die `File`-Schnittstelle haben muss, lang es zu schreiben "``X``: a file like object" und schon wird jeder (oder sollte) wissen, das man da jedes Objekt übergeben kann das sich wie `File` verhält...

Analog verhält es sich auch mit (mehreren möglichen) Rückgabewerten.
Alles lässt sich beschreiben, wenn man den die Lust dazu hat.

<flame> Die Tatsache, das viele es nicht für nötig haben ihre Schnittstellen zu beschreiben, liegt IMO nicht an den von dir genannten Argumenten sondern an der allgemeinen Schreibfaulheit der Programmierer. Den es geht (mache das tagtäglich selber), und das auch bei sehr stark dynamischen Funktionen, die die von mir oben genannten Beispiele in sachen Komplexität in den schatten stellen...Aber klar, Programmierer schreiben viel lieber Produktiven Code anstatt Specs, Docs, oder Tests. Kann das schon verstehen aber, tolerieren auf gar kein Fall.
</flame>


template hat geschrieben:Ja ich gebe zu, das ist in einer nicht strikt typisierten Sprache alles gar nicht so einfach;) Aber es wäre zumindest interessant wie auf bestimmte Situationen reagiert wird. Was ist z.B. wenn eine Regular Expression nicht Matcht. Bekomme ich dann ein None als Ergebnis zurück oder wird doch ne Exception geworfen? Sowas wäre schon irgendwie gut zu wissen.

Da hast du absolut recht. Wenn der Schreiber der library es nicht mal für nötig erachtet bei der Beschreibung der Funktion `Blubb` hinzuschreiben, das bei einen non-match ein `None` zurückgegeben wird, möchte ich garnicht erst seinen source anschauen!


template hat geschrieben:Lange rede, kurzer sinn ich verlasse mich lieber Spezifikationen statt auf Implementationen.
Absolut. Wobei es durchaus auch seinen Reiz haben kann sich mit etwas zu beschäftigen wo keine specs existieren. Z.B.: Ruby :D Ein haufen gehackter kram, ab dennoch sowas von Edel und Python in vielen Bereichen klar überlegen :)

Aber fakt ist, das für ernsthafte Anwendungen in einer Produktivumgebeung auf spezifiziertes gesetzt werden **muss**!!

BlackJack hat geschrieben:Dann wirst Du wohl mit Python ein Problem bekommen. :-)
Nein, es wird ein Problem mit faulen Programmieren bekommen und nicht mit Python. :x Das Pythonistas in der lage sind "Wasserdichte" Specs und Sau gute Dokumentationen zu schreiben, beweisen das Django-Team, GvR, Armin Ronacher, Georg Brandl und auch der größte teil der beteiligten an der Python Dokumentation. Es geht wenn man will!!


Leonidas hat geschrieben:
template hat geschrieben:Lange rede, kurzer sinn ich verlasse mich lieber Spezifikationen statt auf Implementationen.

Wenn du eine Implementation hast, die fehlerhaft ist, dann hilft dir die beste Spezifikation nicht weiter. Letztendlich musst du dich immer nach der Implementation richten.
Und das soll jetzt eine Rechtfertigung sein Leo!? :shock:

Nein, wenn sich eine Implementation nach sehr langer Zeit (Updates) immer noch nicht an die Spezifikation hält, wird sie in den Müll geworfen und nach Konkurrenz ausschau gehalten. Workarounds bringen auf dauer keinem was, sondern sind nur Notlösungen.

Etwas anderes zum Thema passendes sind stark frequentierte API-Änderungen die einen auf lange Sicht auch zum wechsel bewegen. `docutils` ist da so ein Kandidat für das es aber (?) nicht wirklich alternativen gibt...
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Beitragvon poker » Donnerstag 22. November 2007, 16:04

@template
Bitte lass dich von meine geflame nicht davon abhlaten dich mit Python weiter zu beschäftigen! :) Die Dokumentation von Python und vielen Librarys ist in guter Qualität (Kommt zwar nicht an die Quali von der Java-Doc mit...). Das es stellenweise mal eher schlecht ist, wie von dir bemerkt, kommt vor. Aber die Schreiber der Dokumentationen von den Batteries (Der mitgelieferten Python-Lib), sind bestrebt alles auf Hohen Niveau zu halte und besser auch mal aus/Ergänzen, wenn was nicht passt.
Das mit `xml.minidom` ist numal tatsächlich so, das die einfach kein Bock hatten die Informationen hinzuschreiben, da sie, wie von BlackJack erwähnt, ehe standardisiert ist und man mit der Spezifikation ehe im netzt tot geschmissen wird.

Die dachten sich dann "iieeehhh Redundanz" ;) Oder doch eher "Puh, mal wider um das docu schreiben herumgekommen" :D

Mein Tipp: Beschäftige dich auf jedenfall weiter mit Python und lese dir auch mal das offizielle Tutorium durch. Nach eine gewissen Zeit wirst du dich verleiben :) :D
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 22. November 2007, 17:19

poker: Ich sag dir eine Funktion in der stdlib und du sagst mir welche Exceptions geworfen werden können. Zu bemerken ist, dass auch dokumentierte Funktionen durchaus andere Exceptions werfen können, als was der Programmierer dokumentiert hat. Beispielsweise nehmen wir eine Funktion die eine Datei parst. Diese kann möglicherweise einen IOError werfen, den der Programmierer nicht vorhergesehen hat und die also nicht von der Parser-Funktion abgefangen wird, sondern an den Nutzer der Funktion weitergereicht wird.

Wie willst du denn statisch, ohne den Code auszuführen sagen, welche Exceptions geworfen werden können.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Beitragvon poker » Donnerstag 22. November 2007, 18:14

Leonidas:
Wenn meine Funktion angenommen ein File öffnet und es dabei zu einem IOError kommen kann, weise ich in der API darauf hin. Wo ist das Problem?

Und was die OS abhängigen I/O-Exceptions ablangt:
Unter Win die dafür zuständige ehe eine Spezialisierung von der/den standard exception(s) ...

Code: Alles auswählen

from pprint import pprint as pp
import os
try:
    os.remove("not.valid")
except WindowsError, e:
    print e.__class__
    pp(e.__class__.__mro__)

Code: Alles auswählen

<type 'exceptions.WindowsError'>
(<type 'exceptions.WindowsError'>,
 <type 'exceptions.OSError'>,
 <type 'exceptions.EnvironmentError'>,
 <type 'exceptions.StandardError'>,
 <type 'exceptions.Exception'>,
 <type 'exceptions.BaseException'>,
 <type 'object'>)


...also kann man auch gleich `OSError` catchen, da diese Basis auf allen OS vorhanden ist.

Code: Alles auswählen

try:
    os.remove("not.valid")
except OSError, e:
    print e.__class__


Wo, ist da nun das Problem in der API zu schreiben, das bei nichtvorhanden der Datei eine Exception geworfen wird die von der `OSError`-Exception abstammt oder gar `OSError` ist, und somit damit gefangen werden kann?

Code: Alles auswählen

def rf(file):
    """
    Remove the file `file`.

    :para `file`: Path with file name.

    :raises:
       Raises a `OSError` exception or a subclass from this,
       if `file` was not found.
    """

IMO, ist doch mit diesem Beispiel alles "genau" spezifiziert. "subclassed type of `IOError` reicht aus für die jenigen die sich mit Python auskennen ;)

BTW:
remove( path)
Remove the file path. If path is a directory, OSError is raised; see rmdir() below to remove a directory. This is identical to the unlink() function documented below. On Windows, attempting to remove a file that is in use causes an exception to be raised; on Unix, the directory entry is removed but the storage allocated to the file is not made available until the original file is no longer in use. Availability: Macintosh, Unix, Windows.

Man sieht, von hier müsste noch einiges in meiner Beispiel Beschreibung rein.


Oder gibt es doch da was sehr magisches in der stdlib!? Daher
Ich sag dir eine Funktion in der stdlib und du sagst mir welche Exceptions geworfen werden können.
nur zu. wo bei ich denke das dies wohl eher was sehr exotisches ist. Ich bin zu 99% auf nichts gestoßen wo nicht klar wäre was den nun geworfen wird.
BlackJack

Beitragvon BlackJack » Donnerstag 22. November 2007, 18:51

Ich glaube es waren nicht diese supersimplen, sehr betriebssystemnahen Funktionen gemeint. Fast alles wo der Benutzer beliebige Objekte reinstecken kann, die sich nach einem bestimmten "Protokoll" verhalten sollen, können letztendlich beliebige Ausnahmen auslösen weil das eben von den Objekten abhängt, die man dort hineinsteckt.

Selbst beim `os.remove()` kann unter gar nicht so exotischen Umständen ein `UnicodeError` kommen, den Du nicht genannt hast.

Was kann bei `map()` kommen? Was bei `bool()`? Jede Funktion die sich auf andere Objekte abstützt kann schon nicht mehr mit Sicherheit sagen was für Ausnahmen auftreten können, wenn man sie aufruft.
template
User
Beiträge: 29
Registriert: Mittwoch 21. November 2007, 09:44

Beitragvon template » Donnerstag 22. November 2007, 21:38

Bitte lass dich von meine geflame nicht davon abhlaten dich mit Python weiter zu beschäftigen!

Nein, um gottes willen das bestimmt nicht;) Ich finde Python von meinem bisherigen Eindruck her eine sehr durchdachte, praxisnahe, gut lesbare und mächtige Sprache, mit einer sehr guten Standardbibliothek, die für viele meiner Zwecke besser geeignet scheint als alles womit ich mich bisher beschäftigt habe.

Ich meine ich schreibe in der Arbeit auch an Größeren Applikations Servern oder Privat an einer sehr Umfangreichen Windows Anwendung (seit 4 Jahren, über 100.000 Zeilen selbstgeschriebener Code). Diese Dinge werde ich vorerst mal sicher weiter in C/C++ lösen, alleine schon deswegen weil einfach schon viel Code existiert und ich den bestimmt nicht erst portieren möchte;)

Aber für 95% von dem was ich sonst so Schreibe ist eine Script Sprache eigentlich viel besser geeignet, wobei mich bei den meisten fummelige Spracheigenheiten und undurchdate stellen doch immer wieder in die Arme von C++ getrieben haben (wobei das mit sicherheit auch nicht der Weisheit letzer Schluss ist;)). Jetzt habe ich das erste mal das Gefühl wirklich die richtige Script Sprache für mich gefunden zu haben. Es macht einfach irgendwie Spaß mit Python zu arbeiten.

Ich wollte mich auch nochmal bei allen Bedanken die Ihre Freizeit Opfern um den Leuten hier zu helfen und den Einstieg in die Python Welt zu erleichtern.

Allerdings gebe ich zu, das ich doch ganz gerne mal wieder (eben auch mit verschiedenen Leuten) diese Grundsatzfragen diskutiere. Damit will ich mit Sicherheit niemanden angreifen, bloß damit hier kein falscher Eindruck entsteht. Bis auf meine Diskutierwut halte ich mich eigentlich für einen recht umgänglichen Kollegen :)

Wer ist online?

Mitglieder in diesem Forum: Astorek