Erneut ganz herzlichen Dank an alle! Für mich als ziemlichen Anfänger war der erste Beitrag von LukeNukem ganz besonders wertvoll. Vielen Dank für eine Flughöhe, der ich zügig folgen konnte! Allerdings haben mich auch die wertvollen Hinweise der 4-Digit-Kontributoren weitergebracht, was und warum etwas nicht "pythonisch" ist.
Über die teilweise persönlichen Seitenhiebe habe ich einfach hinweggelesen: Weil sowohl leicht verständliche Erklärungen als auch Normenhinweise gerade für Anfänger wichtig sind (und zumindest pädagogisch vereinbar).
Erneut ganz herzlichen Dank an alle!
Instanzenbildung aus Datei
Es ist schon äußerst erstaunlich, daß diese "unlesbare" und "unpythonische" Technik so beliebt und verbreitet ist, daß sich dafür sogar ein eigener Fachausdruck etabliert hat. Er nennt sich "method chaining". Wes McKinney hat darum herum sogar ein eigenes Framework zur statistischen Datenanalyse namens "Pandas" entwickelt.Sirius3 hat geschrieben: Dienstag 25. Mai 2021, 07:28 Bei `familie = Familie().read_csv()` weiß der Leser nicht, ob read_csv nun eine neue Familie oder irgendeinen anderen Typ zurückliefert.
Wenn man einem Einsteiger nichts Neues zeigen und maximal unflexibel bleiben will, ja, klar, dann kann man das so machen. Meine Technik hat allerdings ein paar sehr wesentliche Vorteile, die Dir offensichtlich entgangen sind, denn damit kann ich in einem Rutsch Daten aus verschiedenen Quellen lesen:Sirius3 hat geschrieben: Dienstag 25. Mai 2021, 07:28Code: Alles auswählen
familie = read_family("familie.csv")
Code: Alles auswählen
familie = Familie().read_csv(...).read_csv(...).read_elasticsearch(...).read_redis(...).read_sqldb(...)
@LukeNukem: Etwas verzweifelt in Klassen packen zu wollen, macht man in Sprachen wie Java, die das nicht anders können. Wenn man das mag, kann man Java programmieren. Der Vorteil von Python ist gerade, dass man nur in eine Klasse einbringen muss, was tatsächlich zur Klasse gehört. Und man muss auch nicht Klassen als "Container" für Funktionen verwenden. Wie gesagt, das macht man in Java - in Python ist das fürchterlich überflüssig und nimmt der Sprache einen Großteil ihrer Stärke.
Dass es immer mal wieder Bibliotheken gibt, die spezielle Wege gehen kommt immer mal wieder vor. Aber dein Beispiel mit diesme Rattenschwanz von Funktionsaufrufen ist fürchterlich uznlesbar. Und etwas, das dazu führt, sollte man nun wirklich keinem Anfänger als Option ans Herz legen.
Dass es immer mal wieder Bibliotheken gibt, die spezielle Wege gehen kommt immer mal wieder vor. Aber dein Beispiel mit diesme Rattenschwanz von Funktionsaufrufen ist fürchterlich uznlesbar. Und etwas, das dazu führt, sollte man nun wirklich keinem Anfänger als Option ans Herz legen.
- __blackjack__
- User
- Beiträge: 14056
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@LukeNukem: Gute Variablennamen sind wichtig. Handle ist für eine Dateiobjekt ein falscher Name.
Was OpenCV als API anbietet, richtet sich nach der nicht in Python implementierten OpenCV-Bibliothek, das ist also kein sinnvoller Zeuge für pythonisch/unpythonisch.
Wo wird das bei `numpy` und `scipy` gemacht? Ist mir bis jetzt noch nicht aufgefallen, gib mal Beispiele. Und auch bei Pandas wird das nicht gemacht.
Und `sort()` vs. `sorted()` stützt doch genau das was ich gesagt habe: `sort()` gibt nicht `self` zurück weil es keinen neuen Rückgabewert erzeugt, sondern die bestehende Liste verändert. Da `self` zurückzugeben wäre unpythonisch. Sage übrigens nicht ich, sagt Guido, der sich explizit dazu entschieden hat das so zu regeln.
Was ist denn der Vorteil von dem „train wreck“-Aufruf? „In einem Rutsch“ passiert da nichts, das wird genau so abgearbeitet als wenn die Methoden nicht `self` zurückgeben würden. Also mal konkret:
Welche Vorteile hat der unpythonische Code hier? Beim zweiten weiss ich das `familie` geändert wird, beim ersten ”weiss” man das `familie` *nicht* verändert wird, weil sonst würde man das ja nicht so schreiben. Also schon mal Nachteil das man den ersten Code leicht falsch interpretieren kann.
Das ist übrigens streng genommen auch kein „method chaining“ sondern „method cascading“, nur eben mit dem Mittel „chaining“ weil es keine Syntax oder anderweitige Sprachunterstützung für „cascading“ in Python gibt.
Warum forderst Du mich auf das doch mal mit `classmethod()` zu machen — nachdem Du auf den Beitrag antwortest in dem ich das mit `classmethod()` im Code gezeigt habe? Ist an dem Code etwas unklar?
Die Antwort unter dem Zitat das man den Typ in einer Sprache die auf Duck Typing setzt, besser nicht prüft, passt nicht zum Zitat. Was soll ich *da* besseres zeigen? Weggelassenen Code zu zeigen ist nicht so wirklich sinnvoll.
Auf der einen Seite kritisierst Du wenn ein ``return next(…)`` nicht anfängertauglich ist, auf der anderen Seite machst Du Sirius3 den Vorwurf Anfängern nichts neues zeigen zu wollen.
Das `newline`-Argument bei CSV wegzulassen ist ein *Fehler*, weil das kaputte Dateien zur Folge haben kann. Auf solche Fehler sollte man Newbies auf jeden Fall hinweisen.
Du magst das echt nicht wenn jemand Deinen Code kritisiert, oder?
Was OpenCV als API anbietet, richtet sich nach der nicht in Python implementierten OpenCV-Bibliothek, das ist also kein sinnvoller Zeuge für pythonisch/unpythonisch.
Wo wird das bei `numpy` und `scipy` gemacht? Ist mir bis jetzt noch nicht aufgefallen, gib mal Beispiele. Und auch bei Pandas wird das nicht gemacht.
Und `sort()` vs. `sorted()` stützt doch genau das was ich gesagt habe: `sort()` gibt nicht `self` zurück weil es keinen neuen Rückgabewert erzeugt, sondern die bestehende Liste verändert. Da `self` zurückzugeben wäre unpythonisch. Sage übrigens nicht ich, sagt Guido, der sich explizit dazu entschieden hat das so zu regeln.
Was ist denn der Vorteil von dem „train wreck“-Aufruf? „In einem Rutsch“ passiert da nichts, das wird genau so abgearbeitet als wenn die Methoden nicht `self` zurückgeben würden. Also mal konkret:
Code: Alles auswählen
familie = (
Familie()
.read_csv(...)
.read_csv(...)
.read_elasticsearch(...)
.read_redis(...)
.read_sqldb(...)
)
# vs.
familie = Familie()
familie.read_csv(...)
familie.read_csv(...)
familie.read_elasticsearch(...)
familie.read_redis(...)
familie.read_sqldb(...)
Das ist übrigens streng genommen auch kein „method chaining“ sondern „method cascading“, nur eben mit dem Mittel „chaining“ weil es keine Syntax oder anderweitige Sprachunterstützung für „cascading“ in Python gibt.
Warum forderst Du mich auf das doch mal mit `classmethod()` zu machen — nachdem Du auf den Beitrag antwortest in dem ich das mit `classmethod()` im Code gezeigt habe? Ist an dem Code etwas unklar?
Die Antwort unter dem Zitat das man den Typ in einer Sprache die auf Duck Typing setzt, besser nicht prüft, passt nicht zum Zitat. Was soll ich *da* besseres zeigen? Weggelassenen Code zu zeigen ist nicht so wirklich sinnvoll.
Auf der einen Seite kritisierst Du wenn ein ``return next(…)`` nicht anfängertauglich ist, auf der anderen Seite machst Du Sirius3 den Vorwurf Anfängern nichts neues zeigen zu wollen.
Das `newline`-Argument bei CSV wegzulassen ist ein *Fehler*, weil das kaputte Dateien zur Folge haben kann. Auf solche Fehler sollte man Newbies auf jeden Fall hinweisen.
Du magst das echt nicht wenn jemand Deinen Code kritisiert, oder?
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Also gehört etwas, das eine Instanz einer Klasse erzeugt und zurückgibt, oder das eine Instanz dieser Klasse mit Daten befüllt, für Dich konzeptionell nicht zu dieser Klasse? Interessanter Ansatz. Ein bisschen originell, aber sicherlich interessant.sparrow hat geschrieben: Dienstag 25. Mai 2021, 18:35 @LukeNukem: Etwas verzweifelt in Klassen packen zu wollen, macht man in Sprachen wie Java, die das nicht anders können. Wenn man das mag, kann man Java programmieren. Der Vorteil von Python ist gerade, dass man nur in eine Klasse einbringen muss, was tatsächlich zur Klasse gehört.
Es ist schon lustig, daß Du mir ausgerechnet eine Nähe zu einer Sprache andichten willst, die ich schon nicht leiden konnte, als sie bei meinem damaligen Arbeitgeber entwickelt wurde. Trotzdem kann es sinnvoll sein, Klassen als Container für Funktionen zu benutzen, dafür hat ein gewisser Guido van Rossum in der von ihm kreierten Programmiersprache Python sogar eigens die "staticmethod" eingeführt.sparrow hat geschrieben: Dienstag 25. Mai 2021, 18:35 Und man muss auch nicht Klassen als "Container" für Funktionen verwenden. Wie gesagt, das macht man in Java - in Python ist das fürchterlich überflüssig und nimmt der Sprache einen Großteil ihrer Stärke.
Anscheinend haben wir beide sehr unterschiedliche Vorstellungen von Lesbarkeit. Das ist ja immer auch von der eigenen Erfahrung und Gewohnheit beeinflußt und insofern eine Geschmackssache, über die sich bekanntlich nicht streiten läßt.sparrow hat geschrieben: Dienstag 25. Mai 2021, 18:35 Dass es immer mal wieder Bibliotheken gibt, die spezielle Wege gehen kommt immer mal wieder vor. Aber dein Beispiel mit diesme Rattenschwanz von Funktionsaufrufen ist fürchterlich uznlesbar. Und etwas, das dazu führt, sollte man nun wirklich keinem Anfänger als Option ans Herz legen.
Mach' halt 'nen besseren Vorschlag, wenn Du kannst. Wie wäre es mit "das_dateiobjekt_von_dem_ich_lesen_will"?__blackjack__ hat geschrieben: Dienstag 25. Mai 2021, 18:51 @LukeNukem: Gute Variablennamen sind wichtig. Handle ist für eine Dateiobjekt ein falscher Name.
Das sieht dieser Herr hier aus unerfindlichen Gründen ganz anders und hat dem Thema sogar eigens einen Artikel gewidmet: https://tomaugspurger.github.io/method-chaining__blackjack__ hat geschrieben: Dienstag 25. Mai 2021, 18:51 Und auch bei Pandas wird das nicht gemacht.
Da habe ich mich wohl mißverständlich ausgedrückt -- mit "das" war das Method Chaining gemeint. Das geht nämlich nicht mit einer classmethod, und ich halte meine Lösung tatsächlich für lesbarer, kompakter, und -- vor allem -- für wesentlich flexibler, womit dann auch eine hinreichende Begründung dafür gefunden wäre. In PEP8 steht dazu übrigens auch nichts, und Du darfst es in Deinem Code selbstverständlich gerne anders machen, wenn Dir das besser gefällt.__blackjack__ hat geschrieben: Dienstag 25. Mai 2021, 18:51 Warum forderst Du mich auf das doch mal mit `classmethod()` zu machen — nachdem Du auf den Beitrag antwortest in dem ich das mit `classmethod()` im Code gezeigt habe? Ist an dem Code etwas unklar?
Code: Alles auswählen
familie = Familie()
familie.read_csv(...)
familie.read_csv(...)
[...]
Ach, mit sinnvoller und sachlicher Kritik habe ich tatsächlich nicht nur kein Problem, sie ist mir sogar ausgesprochen willkommen. Aber, weißt Du, kleinkarierte Klugscheißerei von Leuten, die zur Frage des TO bislang noch rein gar nichts beizutragen haben, ist ja weder sinnvolle, noch sachliche Kritik. Ganz im Ernst: Du ziehst Dich daran hoch, wie ich meine Variablen benenne, und willst das ernsthaft zu einer "Kritik" hochstilisieren?__blackjack__ hat geschrieben: Dienstag 25. Mai 2021, 18:51 Du magst das echt nicht wenn jemand Deinen Code kritisiert, oder?![]()
- __blackjack__
- User
- Beiträge: 14056
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@LukeNukem: Ich habe `ifh` im Code anders genannt. Die Frage ist also bereits beantwortet.
In dem verlinkten „method chaining“-Artikel steht nichts was für Deine `read_csv()`-Methode spricht. Im Gegenteil. Das ist weder vom Ansatz her warum Pandas das benutzt, denn da geht es ja darum verschachtelte Funktionsaufrufe lesbarer zu machen. Die gibt es in Deinem Code aber gar nicht.
Und speziell ist auch dort der Autor dagegen das Objekt selbst zu verändern statt ein neues zu erstellen. Das geht in Pandas auch überhaupt nicht. Auch das stützt den Kritikpunkt an Deiner `read_csv()`-Methode.
Es gibt also in Pandas keine Beispiele die Du zeigen könntest.
Im vorletzten Absatz von Deinem Beitrag fehlt offensichtlich Text, der ist so nicht verständlich.
Ganz im Ernst, gute Namen sind wichtig. Von Anfang an. Anfänger sollten sich schlechte Namen gar nicht erst angewöhnen. Weil man das dann erst wieder verlernen muss. Das kann und sollte man sich sparen.
In dem verlinkten „method chaining“-Artikel steht nichts was für Deine `read_csv()`-Methode spricht. Im Gegenteil. Das ist weder vom Ansatz her warum Pandas das benutzt, denn da geht es ja darum verschachtelte Funktionsaufrufe lesbarer zu machen. Die gibt es in Deinem Code aber gar nicht.
Und speziell ist auch dort der Autor dagegen das Objekt selbst zu verändern statt ein neues zu erstellen. Das geht in Pandas auch überhaupt nicht. Auch das stützt den Kritikpunkt an Deiner `read_csv()`-Methode.
Es gibt also in Pandas keine Beispiele die Du zeigen könntest.
Im vorletzten Absatz von Deinem Beitrag fehlt offensichtlich Text, der ist so nicht verständlich.
Ganz im Ernst, gute Namen sind wichtig. Von Anfang an. Anfänger sollten sich schlechte Namen gar nicht erst angewöhnen. Weil man das dann erst wieder verlernen muss. Das kann und sollte man sich sparen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Ja, "input"... bestimmt eine prima Idee, den Namen einer Builtin-Funktion zu mißbrauchen. Viel besser als etwas unverfängliches wie "ifh", das zwar eine Abkürzung ist, aber deutlich mehr Informationen behinhaltet als Dein "input"...__blackjack__ hat geschrieben: Dienstag 25. Mai 2021, 21:00 @LukeNukem: Ich habe `ifh` im Code anders genannt. Die Frage ist also bereits beantwortet.
Das stimmt. Anfänger sollten sich gleich angewöhnen, die Namen von Builtin-Funktionen möglichst kreativ und geichzeitig nichtssagend wiederzuverwenden. Entschuldige, jetzt mal ganz unter uns: Du zeigst hier so einen hahnebüchenen Unfug und wagst es gleichzeitig auch noch, am Code anderer Leute herumzukritteln? Immerhin, das erfordert Mut.__blackjack__ hat geschrieben: Dienstag 25. Mai 2021, 21:00 Ganz im Ernst, gute Namen sind wichtig. Von Anfang an. Anfänger sollten sich schlechte Namen gar nicht erst angewöhnen.

Edit: oh, bitte entschuldige, "input" war von Sirius3, bei Dir heißt es "file". Genauso nichtssagend, wenngleich inkompatibel mit älteren Python-Versionen -- da war "file" nämlich ebenfalls ein Builtin.
- __blackjack__
- User
- Beiträge: 14056
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@LukeNukem: `file` sagt genau aus was es ist, es ist also nicht nichtssagend. Aus dem Kontext ist auch leicht zu erkennen, dass es eine Eingabedatei ist, das wäre also kein grosser Gewinn das `input_file` zu nennen. Es ist ein Gewinn über `ifh`, weil da halt nicht klar ist was das überhaupt heissen sollte. Und darum ging es ja, einen besseren Namen als *das* zu verwenden.
In Python 2 hätte ich `file` natürlich nicht verwendet. Man kann im Forum mehrere Stellen finden, wo ich das bei Code der das verwendet hat, angemerkt habe, mit der Begründung, dass es ein Builtin ist. Python 2 hat sein Mindesthaltbarkeitsdatum überschritten, und ich schreibe keinen neuen Code mehr der Python 2 kompatibel sein muss. Das muss auch kein Anfänger mehr wissen.
In Python 2 hätte ich `file` natürlich nicht verwendet. Man kann im Forum mehrere Stellen finden, wo ich das bei Code der das verwendet hat, angemerkt habe, mit der Begründung, dass es ein Builtin ist. Python 2 hat sein Mindesthaltbarkeitsdatum überschritten, und ich schreibe keinen neuen Code mehr der Python 2 kompatibel sein muss. Das muss auch kein Anfänger mehr wissen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Aus irgendeinem Grund beschleicht mich gerade das Gefühl, daß Du noch nicht so viel Erfahrung hast. Denn "ifh" als Bezeichner für ein Input File Handle habe ich schon in vielen Sprachen gesehen, vermutlich sogar in allen, die ich das Glück oder Unglück hatte, kenenlernen zu dürfen oder zu müssen -- und zwar auch in Python. Daß dieser Bezeichner nicht so abwegig ist, wie es Dir erscheint, siehst Du zum Beispiel hier [1], hier [2], hier [3] und hier [4], und sogar im hiesigen Forum [5]. Ein erfahrener Entwickler sollte so etwas schon oft gesehen haben und daher intuitiv wissen, was mit "ifh" gemeint ist. In Luciano Ramalhos "Fluent Python" hab' ich gerade nochmal nachgeschaut, er benutzt in seinem Kapitel über Context Manager stattdessen lieber "infh" und "outfh". Auch das sollte sich jedem erfahrenen Entwickler auf den ersten Blick erschließen.__blackjack__ hat geschrieben: Dienstag 25. Mai 2021, 22:39 @LukeNukem: `file` sagt genau aus was es ist, es ist also nicht nichtssagend. Aus dem Kontext ist auch leicht zu erkennen, dass es eine Eingabedatei ist, das wäre also kein grosser Gewinn das `input_file` zu nennen. Es ist ein Gewinn über `ifh`, weil da halt nicht klar ist was das überhaupt heissen sollte. Und darum ging es ja, einen besseren Namen als *das* zu verwenden.
Zudem erscheint mir Deine Argumentation ein wenig... inkonsistent. Auf der einen Seite behauptest Du, daß Deine Leser aufgrund des Kontextes leicht erkennen können, daß "file" ein zum Lesen geöffnetes Dateihandle ist. Wenn Du nun annimmst, daß meine Leser das -- wie ich gezeigt habe, absolut gebräuchliche -- "ifh" nicht aus dem Kontext ersehen können, wie muß ich das dann verstehen? Sind meine Leser etwa dümmer als Deine, oder was möchtest Du mir damit sagen?
[1] https://gawron.sdsu.edu/python_for_ss/c ... files.html
[2] https://python-zstandard.readthedocs.io ... essor.html
[3] https://mmcif.wwpdb.org/docs/sw-examples/python/html/
[4] https://numericalalgorithmsgroup.github ... memas.html
[5] viewtopic.php?t=38540
Tjaaa... "file" ist nichtssagend, weil es vollkommen beliebig und mehrdeutig ist. Wenn ich eine Variable namens "file" sehe, dann weiß ich auf den ersten Blick nicht, was damit gemeint ist. Ein Dateiname? Ein Dateideskriptor? Ein Dateihandle? Oder -- wie man es anhand einer etwas verschrobenen Logik auch sehen könnte -- der Inhalt einer Datei? Klar, ich kann ja in den Kontext gucken, aber sollte ein guter Variablenname denn nicht so gewählt sein, daß ich eben gar nicht erst in den Kontext schauen muß? Und, siehst Du, genau deswegen ist das gebräuchliche "ifh" so viel besser, auch als Democode für Einsteiger: es sagt haargenau aus, was dieser Name bezeichnet, nämlich ein zum Lesen geöffnetes Dateihandle (input file handle). Insofern ist es ganz richtig, Bezeichner sollten mit Bedacht gewählt werden und präzise bezeichnen, wofür sie stehen, und diese Forderung sehe ich mit meinem "ifh" wesentlich besser erfüllt als mit Deinem "file" -- was ich mit meinem Beispiel wieder einem anderen Einsteiger demonstriert habe, der in Zukunft ebenfalls wissen wird, was gemeint ist, wenn er auf einen "ifh" oder einen "ofh" oder wie bei Luciano Ramalho auf einen "infh" und einen "outfh" trifft. Yay!__blackjack__ hat geschrieben: Dienstag 25. Mai 2021, 22:39 In Python 2 hätte ich `file` natürlich nicht verwendet. Man kann im Forum mehrere Stellen finden, wo ich das bei Code der das verwendet hat, angemerkt habe, mit der Begründung, dass es ein Builtin ist. Python 2 hat sein Mindesthaltbarkeitsdatum überschritten, und ich schreibe keinen neuen Code mehr der Python 2 kompatibel sein muss. Das muss auch kein Anfänger mehr wissen.

Ja, es ist ein weit verbreitetes Phänomen, dass viele Programmierer kryptische Abkürzungen benutzen, oder etwas Handle nennen, was eigentlich keines ist. Und wie schon oben beschrieben, ist das noch lange kein Rechtfertigungsgrund, wenn man es besser wissen müßte.
`file` ist kein Dateiname, sonst würde es filename heißen. Filehandles benutzt man üblicherweise nicht, weil das was sehr low-level-artiges im System ist, und dann würde man file_handle, oder input_file_handle schreiben, falls es relevant ist, dass es sich hier um ein Eingabe handelt, und es parallel dazu auch ein output_file_handle gibt.
Den Inhalt einer Datei gibt es eigentlich nie, denn es ist nicht relevant, ob Daten nun aus einer Datei stammen, oder gerade erzeugt wurden.
Ganz generell ist ja auch das Problem an kryptischen Abkürzungen, dass man sich leicht vertoppen kann und aus einem ifh ein ofh wird.
`file` ist kein Dateiname, sonst würde es filename heißen. Filehandles benutzt man üblicherweise nicht, weil das was sehr low-level-artiges im System ist, und dann würde man file_handle, oder input_file_handle schreiben, falls es relevant ist, dass es sich hier um ein Eingabe handelt, und es parallel dazu auch ein output_file_handle gibt.
Den Inhalt einer Datei gibt es eigentlich nie, denn es ist nicht relevant, ob Daten nun aus einer Datei stammen, oder gerade erzeugt wurden.
Ganz generell ist ja auch das Problem an kryptischen Abkürzungen, dass man sich leicht vertoppen kann und aus einem ifh ein ofh wird.
Ist ja gut, Mr. Input.Sirius3 hat geschrieben: Mittwoch 26. Mai 2021, 10:28 Ja, es ist ein weit verbreitetes Phänomen, dass viele Programmierer kryptische Abkürzungen benutzen, oder etwas Handle nennen, was eigentlich keines ist. Und wie schon oben beschrieben, ist das noch lange kein Rechtfertigungsgrund, wenn man es besser wissen müßte.
`file` ist kein Dateiname, sonst würde es filename heißen. Filehandles benutzt man üblicherweise nicht, weil das was sehr low-level-artiges im System ist, und dann würde man file_handle, oder input_file_handle schreiben, falls es relevant ist, dass es sich hier um ein Eingabe handelt, und es parallel dazu auch ein output_file_handle gibt.
Den Inhalt einer Datei gibt es eigentlich nie, denn es ist nicht relevant, ob Daten nun aus einer Datei stammen, oder gerade erzeugt wurden.
Ganz generell ist ja auch das Problem an kryptischen Abkürzungen, dass man sich leicht vertoppen kann und aus einem ifh ein ofh wird.

Zunächst möchte ich Dir wärmstens ans Herz legen, noch einmal nachzulesen, was in der Fachsprache als Handle bezeichnet wird, hier [1] ist das ganz gut erklärt.
Weiterhin habe ich bereits (mit Verweisen!) darauf hingewiesen, daß sich bestimmte Abkürzungen nun einmal als Bezeichner in der Breite durchgesetzt haben, ob Dir das nun gefällt oder nicht. In dem Beispiel [5] aus diesem Forum (okay, von 2016) hast Du die Bezeichner "ifh" und "ofh" sogar völlig unkritisch vom TO in Dein eigenes Codebeispiel übernommen. Außerdem ist es leider so, daß ich in den letzten 35 Jahren schon eine ganze Menge Code aus verschiedenen Quellen und in unterschiedlichen Sprachen lesen... mal durfte, mal mußte, und zu meinem großen Leidwesen mußte ich dabei häufig feststellen, daß der Bezeichner "file" von vielen Programmierern und sogar von vielen Entwicklern für jene Dinge verwendet wurde, die ich oben aufgezählt habe. Ich würde sogar sagen, wenn ich für jede solche Verwendung dieses Bezeichners einen Cent bekommen hätte, dann würde ich diesen Beitrag an Bord meiner Hallberg-Rassy schreiben... und ja, auch als Bezeichner für den Inhalt einer Datei habe ich das leider schon gesehen, deswegen hatte ich das auch erwähnt.
Das "sehr low-level-artige im System", von dem Du sprichst, ist zwar -- wie Du im verlinkten Wikipedia-Artikel unter [1] nachlesen kannst -- zwar auch eine Art Dateihandle, wird in der Fachsprache aber üblicherweise als "Dateideskriptor" bezeichnet. Deswegen werden dafür häufig Bezeichner gewählt, IIRC übrigens auch in der Python-Dokumentation, die ein "fd" für "file descriptor" beinhalten. Unter Linux findest Du Informationen zu den Dateideskriptoren, die ein Prozeß geöffnet hat, demzufolge auch unter /proc/<pid>/fd/ und menschenlesbar unter /proc/<pid>/fdinfo/. Übrigens: jede geöffnete Datei wird intern immer über ihren Dateideskriptor angesprochen, auch wenn dafür in Python ein Dateihandle in Form eines "file object", in C ein Zeiger auf eine "FILE"-Struktur oder in C++ eine Instanz von etwas in "iostream", "fstream" oder Ähnlichem ist. Die zugrundeliegenden Systemfunktionen wie open(2), close(2), read(2), write(2) oder lseek(2) benutzen alle nur Dateideskriptoren -- die sogar in der zugehörigen Dokumentation der betreffenden Systemfunktionen als "fd" bezeichnet werden, also wieder mit solchen "kryptischen Abkürzungen". Aber klar, die Leute, die UNIXoide, Linux, und so weiter implementieren, die haben alle noch nichts von Deinen großartigen Ideen zur Wahl "korrekter" Bezeichner gehört und sind deswegen natürlich allesamt vollkommen inkompetent.
Zuletzt finde ich Dein "Argument", daß man sich ja leicht vertippen könne, wirklich zum Totlachen. Denn wenn wir einmal annehmen, daß sich menschliche Bediener einer Tastatur mit einer gewissen Wahrscheinlichkeit bei jedem eingegebenen Zeichen vertippen, dann steigt bei jeder Verwendung Deines Bezeichners mit jedem zusätzlichen Buchstaben die Wahrscheinlichkeit eines Vertippers. Das "Problem" betrifft nämlich nicht nur diese zwar weit verbreiteten, Euren Behauptungen zufolge dennoch "kryptischen" Abkürzungen, sondern auch die von Euch bevorzugten langen Namen -- und diese sogar, wie ich gerade erklärt habe, mit zunehmender Länge sogar in einem noch größerem Ausmaß.
Oh, bitte entschuldige, da fällt mir gerade noch ein kleiner Nachtrag ein: die Python-Entwickler benutzen in ihrer Dokumentation für Dateihandles häufig sogar nur einzelne Buchstaben, wie zum Beispiel in diesem Beispielcode aus PEP343:
Code: Alles auswählen
with opened("/etc/passwd") as f:
for line in f:
print line.rstrip()
Code: Alles auswählen
>>> with open('spamspam.txt', 'w', opener=opener) as f:
... print('This will be written to somedir/spamspam.txt', file=f)
...
[1] https://en.wikipedia.org/wiki/Handle_(computing)
[2] https://docs.python.org/3/library/funct ... =open#open
Und schon wieder schiebst Du die Verantwortung auf andere. Weil der über die rote Ampel läuft, darf ich das auch.
Ein Vertipper bei onput_file_handle fällt sofort auf, bei ofh nicht. Das ist der entscheidende Unterschied: das eine führt zu einem Programmabbruch, das andere im Zweifel einfach nur zu unwiederbringlich kaputten Dateien.
Und schon wieder: nur weil andere für Minimalbeispiele Einbuchstabige Namen verwenden, heißt das noch lange nicht, dass man das gut finden muß, oder gar bewerben.
Ein Vertipper bei onput_file_handle fällt sofort auf, bei ofh nicht. Das ist der entscheidende Unterschied: das eine führt zu einem Programmabbruch, das andere im Zweifel einfach nur zu unwiederbringlich kaputten Dateien.
Und schon wieder: nur weil andere für Minimalbeispiele Einbuchstabige Namen verwenden, heißt das noch lange nicht, dass man das gut finden muß, oder gar bewerben.
- __blackjack__
- User
- Beiträge: 14056
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@LukeNukem: Was in anderen Sprachen üblich ist hat nicht wirklich Gewicht wenn es in Python nicht üblich ist. Lesbarer Code verwendet leicht verständliche Namen. Und man sollte in einer neuen Sprache nicht Namen aus anderen Sprachen, die dort sinnvoll, weil zutreffend waren, einfach blind übertragen. Das es natürlich Leute gibt, die das machen, macht es nicht sinnvoll etwas Handle zu nennen, was gar kein Handle ist.
Ich hätte das `ifh` sogar richtig geraten, weil ich das in C schon öfter gesehen habe, und ziemlich sicher auch schon verwendet habe. Zum einen weil ich das einfach übernommen habe, zum anderen weil es zu der Zeit nicht üblich war eine Autovervollständigung im Editor zu haben. Heute schreibe ich verständlicheren Code und im Code würde beispielsweise `input_file_handle` stehen, aber ich würde nur `ifh` tippen und dann `input_file_handle` über die Autovervollständigung auswählen. Man muss also nicht deutlich mehr tippen, hat aber einen wesentlich sprechenderen Bezeichner im Quelltext. Aber auch wenn es etwas Mehraufwand beim Tippen ist: Quelltext wird öfter gelesen als geschrieben, also macht es Sinn sich beim schreiben die Mühe zu machen, das Lesen zu erleichtern und nicht auf möglichst wenig tippen müssen zu setzen.
Was macht ein Python-Programmierer, Anfänger oder Fortgeschrittener, aus `ifh`‽ Das ist ein völlig sinnfreier, willkürlicher Name, wenn man nicht weiss was das heissen könnte. Zudem noch: was das in einer *anderen* Programmiersprache heissen könnte, denn in Python ist ein Dateiobjekt ja gar kein Handle und der Begriff kommt hauptsächlich im `ctypes`-Modul vor, wo wir dann wieder bei der Programmiersprache C wären, die man mindestens zu einem gewissen Grad können muss, um das sinnvoll und unfallfrei verwenden zu können.
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. Ich weiss also nicht wie Du darauf kommst das ich ”Deine Leser” für dümmer halten könnte.
Zurück zum Kontext in dem ich den Namen bemängelt habe: Ich halte den Leser nicht für dumm, sondern setze einfach nicht voraus, dass der in Python-Quelltext kryptischen Abkürzungen erraten können muss, die aus anderen Programmiersprachen kommen, wo man mit Dateihandles arbeitet. Was ich voraussetze, ist das Quelltext der sprechende Bezeichner verwendet, statt Abkürzungen, leichter verständlich ist, weil der Leser den einfach lesen kann, ohne noch zusätzlich eine Abbildung von Abkürzung zu Klartext im Kopf durchführen zu müssen.
`file` heisst Datei, und damit ist ein Dateiobjekt gemeint in Python. 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. Und Handles und Deskriptoren auch nicht. Ich sehe da also keine Verwechslungsgefahr.
Wenn das jemand hier falsch verwendet, wird er in der Regel auch darauf hingewiesen. Beispiele für `file` für einen Datei*namen*, mit einem entsprechenden Hinweis darauf, sollten sich hier im Forum problemlos finden lassen. Und ja, sehr wahrscheinlich auch Beispiele wo nicht darauf hingewiesen wurde — was kein Grund ist, zu behaupten das wäre kein schlechter, weil falscher Name, und das man da nichts sagen dürfte, nur weil da nicht *immer* was zu gesagt wurde. Es gibt schlecht lesbaren Quelltext da draussen, das ist kein Grund selber solchen zu schreiben, zu verteidigen, oder gar noch zu fördern.
Es gibt historische Konventionen, die unter anderem auf Editoren und Beschränkungen aus der Vergangenheit beruhen. Das ist kein Grund das heute noch zu praktizieren. Man darf sich da auch gerne weiterentwickeln. Ich habe mit BASIC auf dem C64 angefangen, da kann man Variablennamen maximal zwei Zeichen geben und das gesamte Programm verwendet einen einzigen Namensraum. Bei GW-BASIC kann man mehr Zeichen verwenden, aber es gibt einen deutlichen Geschwindigkeitsunterschied zwischen dem Nachschlagen von Namen mit maximal zwei Zeichen und Namen mit mehr Zeichen, der bei den damals üblichen Prozessorgschwindigkeiten in Schleifen durchaus bemerkbar sein kann. Und ich kann mich auch noch an Compiler unter DOS erinnern wo nur die ersten 8 Zeichen von Namen signifikant waren, und das zusammen mit sehr rudimentären Editoren hat zu Namenskonventionen geführt, die einfach nicht mehr zeitgemäss sind.
Dann macht es auch einen Unterschied ob die Sprache statisch typisiert ist, und deshalb eine Deklaration des Typs da steht, die einen sprechenden Typbezeichner enthält. Ein ``f = None`` ist weniger verständlich als ``FILE *f = NULL;``, darum kann man in C mit Namen operieren die in Python zu wenig Informationen enthalten.
`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.
Die ganzen Beschreibungen der Systemaufrufe beziehen sich auf Code der sehr alt ist, oder zumindest Konventionen aus Schnittstellen und Dokumentationen verwendet, die sehr alt sind. Das sind keine modernen Schnittstellen. Und das bezieht sich alles auf C, eine recht „low level“-Programmiersprache. Das ist einfach alles nicht auf moderne Programme und Hochsprachen übertragbar. Ein Ziel beim Entwurf von Python war und ist, dass man damit lesbaren Code schreiben kann. Es macht wenig Sinn die Syntax auf leichte Lesbarkeit zu trimmen und bei den Namen dann anzufangen kryptische Abkürzungen aus ganz anderen Ökosystemen zu verwenden.
Unter der Haube verwendet natürlich auch Python diese Low-Level-Systemschnittstellen, aber der Mehrwert einer Hochsprache ist, dass davon abstrahiert wird, und eine verständlichere API angeboten wird.
Python bietet auch die Systemschicht noch an. Zum Teil einfach aus historischen Gründen — am Anfang war es einfach und praktisch nur eine sehr dünne Schicht über die C-Bibliothek in Python anzubieten um schnell eine dynamische Hochsprache zu haben, in der man fast alles machen kann, was auch in C möglich ist. Das kann heute noch in sehr speziellen Fällen nützlich sein. *Da* kann man dann auch gerne die kryptischen, in diesem Teil üblichen Abkürzungen verwenden. Zum Beispiel `fd` für „file descriptor“ für etwas was tatsächlich ein Dateideskriptor ist. Beispielsweise in ``fd = os.open("test.txt", os.O_RDONLY)``. Da ist das dann auch tatsächlich der Wert den auch die Systemschnittstelle als Dateideskriptor beschreibt: eine ganze Zahl und kein Dateiobjekt das irgendwo innen drin einen Dateideskriptor oder ein Dateihandle kapselt, aber selbst etwas anderes — mehr — ist, als ein opaker Wert, der für eine Datei steht.
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.
Unix/Linux-Systemprogrammierer sind natürlich nicht inkompetent. Die verwenden dort die traditionellen, in dem Bereich idiomatischen Namen. Mache ich auch wenn ich etwas in der Richtung programmiere, weil das dort zur Kultur gehört. Man muss die dort üblichen Namenskonventionen lernen um das Umfeld zu verstehen in dem man programmiert, und es macht keinen Sinn davon abzuweichen, wenn das den Code dann weniger verständlich macht, wenn man etwas was überall `fd` heisst, plötzlich anders nennt.
Das heisst nicht, dass man in einer völlig anderen Programmiersprache, mit einer anderen Kultur, ein ähnliches Abkürzungssystem etablieren muss oder gar sollte, oder gar Abkürzungen übernehmen sollte, die im neuen Kontext gar keinen Sinn ergeben.
Ä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. 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. Wenn man das anders macht, dann macht man etwas das unüblich ist und den Leser überrascht. Zum Beispiel in Form von Fehlern die nicht passieren dürften, wenn man sich da nicht entscheidet das anders zu machen als alle anderen. Das gehört zur Python-Kultur.
Beim Vertippen bei abgekürzten Bezeichnern ist es wahrscheinlicher beim vertippen eine andere Abkürzung zu treffen, also einen ebenfalls gültigen Namen. Und bei `ifh` vs. `ofh` liegen die beiden Tasten, die den Unterschied machen direkt nebeneinander, es ist also verhältnismässig leicht da mal daneben zu tippen. Zumindest bei mir ändert sich die Wahrscheinlichkeit des vertippens nicht durch die Länge, denn wie schon gesagt, wenn ich `input_file_handle` und `output_file_handle` als Namen hätte, würde ich die nur einmal schreiben, und ab da dann nur noch `ifh` und `ofh` und die Autovervollständigung des Editors nutzen. Da ist jetzt natürlich auch die gleiche Gefahr bei `i` und `o` daneben zu tippen, aber es fällt ausgeschrieben schneller auf, weil `input` anders aussieht als `output` und mehr ”Fläche” bietet als `i` und `o`. Spätestens wenn man es (vor)liest fällt es deutlich auf. Bei Abkürzungen kann so etwas leichter durchrutschen, weil man ja ”weiss”, dass an der Stelle beispielsweise die Eingabedatei gemeint ist, und man beim vorlesen von `ofh` trotzdem „input file handle“ (vor)liest, weil dass zwar das richtige wäre — es ist halt nur nicht das, was da steht.
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. Das ist Wegwerfcode, mit sehr wenigen Zeilen und Namen, der in einer Umgebung geschrieben ist, wo man auch leicht interaktiv herausfinden kann was für einen Typ und welche Eigenschaften ein Objekt hinter einem kurzen Namen hat. Und in der Regel steht da auch noch (Kon)Text vor und/oder nach dem Quelltextschnippsel aus der interaktiven Sitzung im Beitrag. Das bedeutet selbstverständlich nicht, dass es sinnvoll ist, grössere Programme auf diese Weise, in diesem Stil zu schreiben. Ein Kontext wo ich so etwas noch tolerabel finde sind Notebooks, wo der entsprechende Kontext dann auch in den Texten vor und nach den Zellen mit Code steht, und wo die Leserschaft an kryptisch kompakt gewöhnt ist. Das ist da auch wieder eine Kulturfrage. Wobei auch dort die Einstiegshürde niedriger wäre wenn man nicht kryptisch kompakt bleibt.
Ich hätte das `ifh` sogar richtig geraten, weil ich das in C schon öfter gesehen habe, und ziemlich sicher auch schon verwendet habe. Zum einen weil ich das einfach übernommen habe, zum anderen weil es zu der Zeit nicht üblich war eine Autovervollständigung im Editor zu haben. Heute schreibe ich verständlicheren Code und im Code würde beispielsweise `input_file_handle` stehen, aber ich würde nur `ifh` tippen und dann `input_file_handle` über die Autovervollständigung auswählen. Man muss also nicht deutlich mehr tippen, hat aber einen wesentlich sprechenderen Bezeichner im Quelltext. Aber auch wenn es etwas Mehraufwand beim Tippen ist: Quelltext wird öfter gelesen als geschrieben, also macht es Sinn sich beim schreiben die Mühe zu machen, das Lesen zu erleichtern und nicht auf möglichst wenig tippen müssen zu setzen.
Was macht ein Python-Programmierer, Anfänger oder Fortgeschrittener, aus `ifh`‽ Das ist ein völlig sinnfreier, willkürlicher Name, wenn man nicht weiss was das heissen könnte. Zudem noch: was das in einer *anderen* Programmiersprache heissen könnte, denn in Python ist ein Dateiobjekt ja gar kein Handle und der Begriff kommt hauptsächlich im `ctypes`-Modul vor, wo wir dann wieder bei der Programmiersprache C wären, die man mindestens zu einem gewissen Grad können muss, um das sinnvoll und unfallfrei verwenden zu können.
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. Ich weiss also nicht wie Du darauf kommst das ich ”Deine Leser” für dümmer halten könnte.
Zurück zum Kontext in dem ich den Namen bemängelt habe: Ich halte den Leser nicht für dumm, sondern setze einfach nicht voraus, dass der in Python-Quelltext kryptischen Abkürzungen erraten können muss, die aus anderen Programmiersprachen kommen, wo man mit Dateihandles arbeitet. Was ich voraussetze, ist das Quelltext der sprechende Bezeichner verwendet, statt Abkürzungen, leichter verständlich ist, weil der Leser den einfach lesen kann, ohne noch zusätzlich eine Abbildung von Abkürzung zu Klartext im Kopf durchführen zu müssen.
`file` heisst Datei, und damit ist ein Dateiobjekt gemeint in Python. 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. Und Handles und Deskriptoren auch nicht. Ich sehe da also keine Verwechslungsgefahr.
Wenn das jemand hier falsch verwendet, wird er in der Regel auch darauf hingewiesen. Beispiele für `file` für einen Datei*namen*, mit einem entsprechenden Hinweis darauf, sollten sich hier im Forum problemlos finden lassen. Und ja, sehr wahrscheinlich auch Beispiele wo nicht darauf hingewiesen wurde — was kein Grund ist, zu behaupten das wäre kein schlechter, weil falscher Name, und das man da nichts sagen dürfte, nur weil da nicht *immer* was zu gesagt wurde. Es gibt schlecht lesbaren Quelltext da draussen, das ist kein Grund selber solchen zu schreiben, zu verteidigen, oder gar noch zu fördern.
Es gibt historische Konventionen, die unter anderem auf Editoren und Beschränkungen aus der Vergangenheit beruhen. Das ist kein Grund das heute noch zu praktizieren. Man darf sich da auch gerne weiterentwickeln. Ich habe mit BASIC auf dem C64 angefangen, da kann man Variablennamen maximal zwei Zeichen geben und das gesamte Programm verwendet einen einzigen Namensraum. Bei GW-BASIC kann man mehr Zeichen verwenden, aber es gibt einen deutlichen Geschwindigkeitsunterschied zwischen dem Nachschlagen von Namen mit maximal zwei Zeichen und Namen mit mehr Zeichen, der bei den damals üblichen Prozessorgschwindigkeiten in Schleifen durchaus bemerkbar sein kann. Und ich kann mich auch noch an Compiler unter DOS erinnern wo nur die ersten 8 Zeichen von Namen signifikant waren, und das zusammen mit sehr rudimentären Editoren hat zu Namenskonventionen geführt, die einfach nicht mehr zeitgemäss sind.
Dann macht es auch einen Unterschied ob die Sprache statisch typisiert ist, und deshalb eine Deklaration des Typs da steht, die einen sprechenden Typbezeichner enthält. Ein ``f = None`` ist weniger verständlich als ``FILE *f = NULL;``, darum kann man in C mit Namen operieren die in Python zu wenig Informationen enthalten.
`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.
Die ganzen Beschreibungen der Systemaufrufe beziehen sich auf Code der sehr alt ist, oder zumindest Konventionen aus Schnittstellen und Dokumentationen verwendet, die sehr alt sind. Das sind keine modernen Schnittstellen. Und das bezieht sich alles auf C, eine recht „low level“-Programmiersprache. Das ist einfach alles nicht auf moderne Programme und Hochsprachen übertragbar. Ein Ziel beim Entwurf von Python war und ist, dass man damit lesbaren Code schreiben kann. Es macht wenig Sinn die Syntax auf leichte Lesbarkeit zu trimmen und bei den Namen dann anzufangen kryptische Abkürzungen aus ganz anderen Ökosystemen zu verwenden.
Unter der Haube verwendet natürlich auch Python diese Low-Level-Systemschnittstellen, aber der Mehrwert einer Hochsprache ist, dass davon abstrahiert wird, und eine verständlichere API angeboten wird.
Python bietet auch die Systemschicht noch an. Zum Teil einfach aus historischen Gründen — am Anfang war es einfach und praktisch nur eine sehr dünne Schicht über die C-Bibliothek in Python anzubieten um schnell eine dynamische Hochsprache zu haben, in der man fast alles machen kann, was auch in C möglich ist. Das kann heute noch in sehr speziellen Fällen nützlich sein. *Da* kann man dann auch gerne die kryptischen, in diesem Teil üblichen Abkürzungen verwenden. Zum Beispiel `fd` für „file descriptor“ für etwas was tatsächlich ein Dateideskriptor ist. Beispielsweise in ``fd = os.open("test.txt", os.O_RDONLY)``. Da ist das dann auch tatsächlich der Wert den auch die Systemschnittstelle als Dateideskriptor beschreibt: eine ganze Zahl und kein Dateiobjekt das irgendwo innen drin einen Dateideskriptor oder ein Dateihandle kapselt, aber selbst etwas anderes — mehr — ist, als ein opaker Wert, der für eine Datei steht.
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.
Unix/Linux-Systemprogrammierer sind natürlich nicht inkompetent. Die verwenden dort die traditionellen, in dem Bereich idiomatischen Namen. Mache ich auch wenn ich etwas in der Richtung programmiere, weil das dort zur Kultur gehört. Man muss die dort üblichen Namenskonventionen lernen um das Umfeld zu verstehen in dem man programmiert, und es macht keinen Sinn davon abzuweichen, wenn das den Code dann weniger verständlich macht, wenn man etwas was überall `fd` heisst, plötzlich anders nennt.
Das heisst nicht, dass man in einer völlig anderen Programmiersprache, mit einer anderen Kultur, ein ähnliches Abkürzungssystem etablieren muss oder gar sollte, oder gar Abkürzungen übernehmen sollte, die im neuen Kontext gar keinen Sinn ergeben.
Ä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. 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. Wenn man das anders macht, dann macht man etwas das unüblich ist und den Leser überrascht. Zum Beispiel in Form von Fehlern die nicht passieren dürften, wenn man sich da nicht entscheidet das anders zu machen als alle anderen. Das gehört zur Python-Kultur.
Beim Vertippen bei abgekürzten Bezeichnern ist es wahrscheinlicher beim vertippen eine andere Abkürzung zu treffen, also einen ebenfalls gültigen Namen. Und bei `ifh` vs. `ofh` liegen die beiden Tasten, die den Unterschied machen direkt nebeneinander, es ist also verhältnismässig leicht da mal daneben zu tippen. Zumindest bei mir ändert sich die Wahrscheinlichkeit des vertippens nicht durch die Länge, denn wie schon gesagt, wenn ich `input_file_handle` und `output_file_handle` als Namen hätte, würde ich die nur einmal schreiben, und ab da dann nur noch `ifh` und `ofh` und die Autovervollständigung des Editors nutzen. Da ist jetzt natürlich auch die gleiche Gefahr bei `i` und `o` daneben zu tippen, aber es fällt ausgeschrieben schneller auf, weil `input` anders aussieht als `output` und mehr ”Fläche” bietet als `i` und `o`. Spätestens wenn man es (vor)liest fällt es deutlich auf. Bei Abkürzungen kann so etwas leichter durchrutschen, weil man ja ”weiss”, dass an der Stelle beispielsweise die Eingabedatei gemeint ist, und man beim vorlesen von `ofh` trotzdem „input file handle“ (vor)liest, weil dass zwar das richtige wäre — es ist halt nur nicht das, was da steht.
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. Das ist Wegwerfcode, mit sehr wenigen Zeilen und Namen, der in einer Umgebung geschrieben ist, wo man auch leicht interaktiv herausfinden kann was für einen Typ und welche Eigenschaften ein Objekt hinter einem kurzen Namen hat. Und in der Regel steht da auch noch (Kon)Text vor und/oder nach dem Quelltextschnippsel aus der interaktiven Sitzung im Beitrag. Das bedeutet selbstverständlich nicht, dass es sinnvoll ist, grössere Programme auf diese Weise, in diesem Stil zu schreiben. Ein Kontext wo ich so etwas noch tolerabel finde sind Notebooks, wo der entsprechende Kontext dann auch in den Texten vor und nach den Zellen mit Code steht, und wo die Leserschaft an kryptisch kompakt gewöhnt ist. Das ist da auch wieder eine Kulturfrage. Wobei auch dort die Einstiegshürde niedriger wäre wenn man nicht kryptisch kompakt bleibt.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Das habe ich zum Glück nicht nötig, sondern verweise lediglich auf übliche Konventionen. Und zwar auf Konventionen, die nicht nur, aber auch in Python häufig genutzt werden, und zwar auch von Leuten, die gemeinhin zu den Gurus dieser Sprache gezählt werden.Sirius3 hat geschrieben: Mittwoch 26. Mai 2021, 13:52 Und schon wieder schiebst Du die Verantwortung auf andere. Weil der über die rote Ampel läuft, darf ich das auch.
Wow, Beweis durch Behauptung? Mir fällt ein Vertipper in einem Bezeichner mit drei Buchstaben schneller auf -- über Dein onput_file habe ich jetzt zweimal unbeanstandet hinweg gelesen, ohne es zu bemerken, obwohl die Levenshtein-Distanz zum gewünschten "output_file" sogar 2 beträgt, mit anderen Worten: da sind gleich zwei Fehler drin, einmal das Vertauschen von 'u' gegen 'n' und dann das Weglassen von 't'.Sirius3 hat geschrieben: Mittwoch 26. Mai 2021, 13:52 Ein Vertipper bei onput_file_handle fällt sofort auf, bei ofh nicht.
Nebenbei ist Dein "output_file" immer noch keine Datei, sondern ein Dateihandle.
Noch ein Beweis durch Behauptung? Langsam wird Deine "Argumentation" wirklich zu lächerlich. Ist das Dein Ziel? Mich so lange mit kindischem Unfug und unbelegten Behauptungen zu nerven, bis ich die Klappe halte?Sirius3 hat geschrieben: Mittwoch 26. Mai 2021, 13:52 Das ist der entscheidende Unterschied: das eine führt zu einem Programmabbruch, das andere im Zweifel einfach nur zu unwiederbringlich kaputten Dateien.
Meine Güte, jetzt wird es auch noch peinlich. Wir reden hier nicht von irgendwelchen beliebigen anderen, sondern von den Core-Developern einer Sprache, die Du so "gut" "beherrschst", daß Du gängige Konventionen nicht kennst und die Bezeichner von Builtin-Funktionen als Variablennamen mißbrauchst. Ehrlich, wenn mir so ein Lapsus wie die Sache mit "input" passiert wäre, würde ich schön die Klappe halten und mich eine Weile lang schämen gehen, anstatt weiterhin einen auf dicke Hose zu machen und herumzukrakeelen.Sirius3 hat geschrieben: Mittwoch 26. Mai 2021, 13:52 Und schon wieder: nur weil andere für Minimalbeispiele Einbuchstabige Namen verwenden, heißt das noch lange nicht, dass man das gut finden muß, oder gar bewerben.
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 @LukeNukem: Was in anderen Sprachen üblich ist
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 Lesbarer Code verwendet leicht verständliche Namen.
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()".__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.
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.
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.__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35 Aber auch wenn es etwas Mehraufwand beim Tippen ist: Quelltext wird öfter gelesen als geschrieben,
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!
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.__blackjack__ hat geschrieben: Mittwoch 26. Mai 2021, 16:35 Was macht ein Python-Programmierer, Anfänger oder Fortgeschrittener, aus `ifh`‽
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.
Wie gesagt: 108 Verwendungen des Fachbegriffs "file handle" in der offiziellen Dokumentation von Python.__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,
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 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.
Weil Deine Leser laut Deiner Aussage in den Kontext schauen können, und meine nicht.__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.
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 `file` heisst Datei, und damit ist ein Dateiobjekt gemeint in Python.
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 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.
Das stelle ich nicht in Frage. Warum sollte ich auch? Mein Code ist lesbar.__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.
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 `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.
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 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.
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?__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.
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.
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 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.
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?__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.

Gut, dass wir das geklärt hätten...
Ich verstehe nur nicht, warum die Builtin-Funktionen kein „h“ im Namen haben, die sind ja alle in C geschrieben und damit existieren im Python-Programm nur „Anfasser“ dafür.

Code: Alles auswählen
#!/usr/bin/env python3
def mfh():
ish = input("Enter number: ")
iih = int(ish)
oih = iih + 42
osh = f"Result: {oih}"
print(osh)
if __name__ == "__main__":
mfh()