__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
@LukeNukem: Was in anderen Sprachen üblich ist
Wie ich mit meinen Links bewiesen habe, sind die Bezeichner "ifh" und "ofh" auch in Python weit verbreitet. In PEP8 steht, wie gesagt, auch nichts dazu.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
Lesbarer Code verwendet leicht verständliche Namen.
Ja, genau. "ifh" und "ofh" sind leicht verständliche Namen, und deswegen werden sie seit langer Zeit und von mehreren Generationen von Entwicklern gerne verwendet. Auch in Python. Und in Python-Vorlesungen. Und in Python-Lehrbüchern.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
Das es natürlich Leute gibt, die das machen, macht es nicht sinnvoll etwas Handle zu nennen, was gar kein Handle ist.
Es ist ein Handle. Das englische Wort "Handle" heißt übersetzt so etwas wie "Griff" und beschreibt ein Etwas, mit dem man ein anderes Etwas anfassen und händeln (sic!) kann. Zum Beispiel ein "panhandle", was übersetzt so viel bedeutet wie "Pfannengriff". Im Informatikkontext ist ein "Handle" also eine Art "Griff", damit man etwas "anfassen" kann. Zum Beispiel eine Datei oder eine Netzwerkverbindung. Insofern gehört das, was Python als "file object" oder "file-like object" bezeichnet, absolut eindeutig und unzweifelhaft in die Kategorie, die der kompetente Informatiker als "Handles" bezeichnet. Demzufolge benutzt dann auch die Dokumentation von Python diesen Begriff dann auch -- laut Google -- an 108 Stellen. Zum Beispiel in der Methode "zipfile.ZipFile.open()".
Daß die Dateihandles, die die Funktion "open()" und die Methode "zipfile.ZipFile.open()" zurückgeben, gleichzeitig auch das Context Manager-Protokoll mit den Methoden __enter__() und __exit__() unterstützen, ändert nichts daran, daß ein "file"-Objekt oder ein "file-like"-Objekt trotzdem immer noch Dateihandles sind. Also Handles. Bitte lies den Wikipedia-Artikel, den ich verlinkt habe. Danke.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
Aber auch wenn es etwas Mehraufwand beim Tippen ist: Quelltext wird öfter gelesen als geschrieben,
Ein Name wie "input_file_handle" ist, verglichen mit "ifh", allerdings auch mehr Aufwand beim Lesen. Für natürliche Sprachen gibt es dazu spannende wissenschaftliche Untersuchungen, die interessante Rückschlüsse auch auf formalisierte Sprachen wie eine Progrmmiersprache zulassen. Wenngleich formalisierte Sprachen allerdings noch einige andere Aspekte haben: die muß nicht nur ein Mensch, sondern auch ein Compiler oder Interpreter verstehen, und während Menschen bei natürlichen Sprachen viele Worte schon an ihrem "Wortbild" erkennen und obendrein einen Korrekturfilter im Kopf haben, so daß "Klappe" und "Kleppe" nahezu verzögerungsfrei gelesen werden können, sind die Anforderungen beim Lesen einer formalisierten Sprache wesentlich höher. Wer von uns kennt das nicht, daß man einen blöden Tippfehler gemacht hat und ihn trotz Traceback mit detaillierten Informationen nicht sieht? Ist mir gerade heute mit "nunber" und "number" passiert.
Hinzu kommt, daß ein gewisser Guido van Rossum sich im Falle der von ihm kreierten Programmiersprache einerseits bewußt und aktiv gegen die exzessive Verwendung von Sonderzeichen entschieden hat, weswegen wir Python-Coder uns glücklicherweise nicht mit den in anderen Sprachen beliebten Klammerorgien herumplagen müssen. Sonderzeichen machen das Lesen von Texten noch einmal schwieriger für uns Menschen, was unter anderem dazu führt, daß sich Python-Code wesentlich leichter und flüssiger lesen läßt als zum Beispiel Perl-, Ruby-, oder PHP-Code. Yay!
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
Was macht ein Python-Programmierer, Anfänger oder Fortgeschrittener, aus `ifh`‽
Im allerschlimmsten Fall dasselbe wie Dein Leser: er schaut in den Kontext. In dem Fall, den Ihr beide hier in Bausch und Bogen verdammt, ist das sogar ganz einfach, denn der Bezeichner wird lediglich an genau zwei Stellen im Code benutzt, die lustigerweise auch noch in zwei Zeilen direkt untereinander stehen. Und erfahrenere Entwickler wissen sowieso, was ein "ifh" ist, während Dein nichtssagendes, generisches "file" den erfahreneren Entwicklern erstens ohne Kontext rein gar und überhaupt nichts sagt, und zweitens die Fußnägel aufrollen läßt, weil es einen ehemaligen Builtin-Bezeichner benutzt und damit die Abwärtskompatibilität bricht.
Deine weiter oben geäußerte Einlassung, daß Python2 ja EOL und daher für Dich unwichtig sei, mag in Deinem kleinen Universum ja zutreffen. Meine berufliche Erfahrung nicht nur, aber auch mit Banken, Versicherungen, Mobilfunkern und anderen internationalen Großkonzernen weiß dagegen, daß meine Entwickler nicht selten nur Codelieferant für Infrastrukturen sind, auf deren Ausgestaltung und Aktualität wir wenig bis keinen Einfluß haben -- oder sogar beim Pitch schon 'rausfliegen, weil wir die dort in Verwendung befindliche Uralt-Architekturen nicht mehr unterstützen können oder wollen. Aus meiner Zeit bei Sun Microsystems kann ich mich immer noch gut an einen Fall erinnern, als wir einen bekannten Mobilfunkkonzern bei der Migration seiner alten Architektur auf der Basis von Solaris 2.6 / SunOS 5.6 auf Solaris 8 / SunOS 5.9 unterstützt haben -- zwei Wochen, NACHDEM Solaris 8 abgekündigt worden war.
Ein anderes Beispiel aus der jüngeren Vergangenheit betraf übrigens RHEL6, das standardmäßig noch mit einem GCC 4.4 ausgeliefert wurde, der infolgedessen keine Unterstützung für die neueren C++-Standards ab C++11 aufwärts hatte. Es gab / gibt zwar von RedHat eine etwas... krude Veranstaltung namens "Developer Toolkit", aber Du kannst halt nicht mal so eben als Lieferant zu einem extrem auf Langlebigkeit und Stabilität bedachten Großkonzern gehen und den Leuten da verklickern, daß sie jetzt bitte zusätzlich zum systemweiten Compiler noch irgendeinen obskuren Hack mit einem aktuellen Compiler, einer neuen Libc und einer neuen libstdc++ installieren soll. Dann gucken die auf einmal ganz unentspannt, fragen Dich, ob Du noch alle Latten am Zaun hast, und begleiten Dich freundlich zur Tür.
Zudem gibt es im Python-Universum neben dem Standard-Interpreter CPython ja auch noch andere Interpreter, etwa Pypy, Jython, und IronPython, sowie diverse Trans- und Compiler wie nuitka, Brython, Shed Skin oder PyJS. Zumindest Jython, Shed Skin und PyJS unterstützen Python3 meines Wissens noch nicht. Aus diesen Erfahrungen und Gründen befürchte ich, daß Python2 uns noch länger erhalten bleiben wird, als uns lieb ist, und auch wenn ich in meinem Code genug Features benutzt habe, die Python3 voraussetzen, halte ich ein gewisses Maß an Abwärtskompatibilität immer noch für wichtig und richtig -- und man muß ja nun wirklich nicht ohne Not ausgerechnet bei den frei wählbaren Bezeichnern anfangen, sie zu brechen.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
denn in Python ist ein Dateiobjekt ja gar kein Handle und der Begriff kommt hauptsächlich im `ctypes`-Modul vor,
Wie gesagt: 108 Verwendungen des Fachbegriffs "file handle" in der offiziellen Dokumentation von Python.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
Falls man in C programmiert und es nur um eine einzige Datei in der Funktion gibt, die `read_csv()` heisst, dann würde auch da `fh` oder gar nur `f` für das Dateihandle keinen Unterschied machen, für jemanden der C und diese Namenskonvention kennt. Da ist auch ohne das `i` klar, dass es eine Eingabedatei ist die zum Lesen geöffnet wird.
Auch in C und C++ würde die betreffende Variable bei mir "ifh" heißen bzw. "ifs" in C++, denn dort wäre es ja ein mit dem Dateihandle verknüpfter Stream.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
Ich weiss also nicht wie Du darauf kommst das ich ”Deine Leser” für dümmer halten könnte.
Weil Deine Leser laut Deiner Aussage in den Kontext schauen können, und meine nicht.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
`file` heisst Datei, und damit ist ein Dateiobjekt gemeint in Python.
Du sagst es, genau das meine ich doch! Siehst Du den Unterschied? Eine Datei eine Datei und weder ein Dateiobjekt, noch ein Dateihandle. Um aus einer Datei ein Dateihandle, Dateiobjekt, oder "file-like object" zu machen, muß man sie mit open(), mmap.mmap(), oder os.open() öffnen, und das, was dabei herauskommt, ist wieder keine Datei, sondern eine Art "Anfasser", mit dem ich auf die Inhalte der Datei zugreifen kann. Richtig ist, daß die betreffenden Funktionen zwar das Betriebssystem anweisen können, eine neue Datei zu erstellen oder eine vorhandene zu leeren, aber dafür ist alleine das Betriebssystem zuständig, und in meinem Programm habe ich dann immer noch keine Datei, sondern nur eine Art Griff dafür. Ein Handle also. Oder ein "file object". Oder ein "file-like object". Oder ein "file handle".
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
Wenn man „duck typing“ hinzu zieht ist das irgend ein Objekt das entsprechend mindestens ein `read()` oder ein `write()` und sich darauf abstützende Methoden bietet, und eine `close()`-Methode. Ein Datei*name* bietet das nicht.
Du hast da nicht ganz unrecht, aber anstelle des Duck Typing sehe ich das eher in einem Python-Feature, das als "Protokolle" oder "protocols" bekannt ist. Das ist zwar -- genau wie das Duck Typing -- kein besonderes Alleinstellungsmerkmal von Python, wird aber in Python auch intern besonders exzessiv genutzt.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
Es gibt schlecht lesbaren Quelltext da draussen, das ist kein Grund selber solchen zu schreiben, zu verteidigen, oder gar noch zu fördern.
Das stelle ich nicht in Frage. Warum sollte ich auch? Mein Code ist lesbar.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
`ifh` kann in Python ein Dateiobjekt gar nicht präzise beschreiben, weil der Handle-Teil des Namens schlicht falsch ist. Das Gegenteil von einer präzisen Beschreibung des Wertes.
Also nach einer ellenlangen Diskussion, in der Ihr meine Ausführungen geflissentlich ignoriert und gebetsmühlenartig immer wieder denselben Unsinn wiederholt habt, sind wir mittlerweile an einem Punkt angelangt, an dem in meinen 67 (wc -l) bzw. 47 (sloccount) Zeilen Code lediglich ein AUCH IN PYTHON ABSOLUT ÜBLICHER UND GEBRÄUCHLICHER Bezeichner "kritisiert" wird, der zudem in nur zwei direkt untereinander liegenden Zeilen benutzt wird -- und an einem Punkt, indem Ihr trotz mehrfacher Hinweise und Links immer noch nicht verstanden habt, daß ein "file handle" und ein "file object" exakt dasselbe sind.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
Das mit den sprechenden Bezeichnern ist nicht allein unsere grossartige Idee. Das sagen einem Informatiklehrer, das sagen einem Professoren und Tutoren in der Uni, das sagen einem Leute die anderen Programmieren beibringen, das sagen einem Leute die beruflich programmieren, und anderen weitergeben wo sie Probleme sehen und wie man das besser machen kann.
Ja, genau, und haargenau deswegen benutze ich sprechende Bezeichner. Wenn sie nicht mit Dir sprechen wollen, naja... vielleicht liegt es ja nicht an dem Bezeichner? Ich meine, andere benutzen denselben Bezeichner, auch in Python, und kommen ganz wunderbar klar. Weißt Du, ich habe noch eine andere Erfahrung in der professionellen Systemadministration und Softwareentwicklung gemacht: wenn tausende von Benutzern mit einer Software gut klarkommen und einer oder zwei nicht, dann liegt es in der Regel nicht an der Software. Aber Du bist in guter Gesellschaft, mir zum Beispiel geht es mit Windows und Office-Software so.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
Ähnliches gilt für das „method chaining“: Bei Methoden in JavaScript überlege ich in der Regel wenn die Methode keinen Rückgabewert hat, ob ich da `this` zurückgebe. Weil das dort in der Standardbibliothek und vielen anderen Bibliotheken üblich ist, und der Leser das erwartet, ohne zu erwarten das die Methode das Objekt auf dem die Methode aufgerufen wird, durch den Aufruf unverändert bleibt.
Tjaaa... und jetzt denk' zum Beispiel mal an Tkinter / Tix. Da ärgere ich mich regelmäßig darüber, daß der Effbot das mit dem Chaining nicht gemacht hat. Wie viel kompakter und lesbarer könnte man den Code dafür schreiben, wenn die <zensiert>-Methoden wie .pack() und .grid() einfach das Objekt zurückgäben, auf dem sie aufgerufen wurden?
Wobei in diesem Fall der Vorwurf ja sogar stimmen würde, daß das Objekt unverändert zurückgegeben wird. Das jedoch stimmt in meinem Fall ja gerade nicht so (und bei .sort(), das ein sehr beliebter und tausendfach gesehener Fehler bei Anfängern ist übrigens auch nicht). Im Gegenteil: .sort() sortiert, verändert also das Objekt, und meine Methode .read_csv() verändert das Objekt sogar inhaltlich. Vermutlich gibt es gute Gründe dafür, warum Guidos Ausführungen zu .sort() lediglich als E-Mail vorliegen und es nicht in PEP8 geschafft haben.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
In Python ist das aber anders, weil dort die Standardbibliothek ”entschieden” hat, das Methoden die das Objekt verändern `None` zurückgeben, und nicht `self`. Das ist eine bewusste Entscheidung die getroffen und auf Nachfrage so kommuniziert wurde. Die Standardbibliothek hält sich daran, und die meisten verbreiteten Bibliotheken auch. Beispielsweise auch das von Dir genannte Pandas.
In der Standardbibliothek hält sich beispielsweise das pstats-Modul nicht daran, und wie ich oben gezeigt habe, auch Pandas nicht. Es ist in Pandas kein Problem, einen Dataframe zu filtern, dann zu sortieren, dann einen weiteren Filter auf das solcherart sortierte auszuführen und das Ergebnis dann noch weiter zu verarbeiten. Es ist nicht nur kein Problem, sondern es ist sogar absolut üblich! Hast Du schon einmal praktisch mit Pandas gearbeitet? Dann müßtest Du das wissen.
__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35
Du wirst auch von mir Quelltext aus interaktiven Shells hier im Forum finden, die einbuchstabige Namen verwenden, und kryptische Abkürzungen, und sehr generische Namen, bei generischen Beispielen.
Eure generischen Namen wie "file" und "input" habe ich ja gesehen... allerdings bisher wenig guten Code von Euch. Wir können das ja spaßeshalber mal so machen: Ihr beide schreibt einfach jeweils mal eine eigene Implementierung für das Problem des TO, das ist ja vergleichsweise trivial, und ich schreibe dazu dann mal etwas in der Richtung, wie ich Produktionscode schreiben würde. Okay, ich würde ausnahmsweise die Tests weglassen, da würden meine Leute mich bei Produktionscode ebenso teeren und federn wie ich sie im umgekehrten Fall... Wenn wir fertig sind, laden wir das Ganze zu einem Filehoster hoch und mailen dem TO jeweils einen Link auf unsere Codes, und wenn er alle Links hat, sagt er Bescheid und dann legen wir die jeweiligen Lösungen einfach mal nebeneinander. Vermutlich kann unser TO aus diesen praktischen Lösungen wesentlich mehr lernen und verstehen als aus dem kindischen Herumgehacke auf Bezeichnern und Fachausdrücken. Na, traut Ihr Euch?
