Warum print-Anweisung ist nicht Pythonic? [geschlossen]
-
20-08-2019 - |
Frage
Diese Frage wurde mir Lauschangriff für eine ganze Weile (wie von meine vorherige Frage ): warum genau ist print(x)
besser (was als mehr pythonic definiert ist) als print x
Für diejenigen, die nicht wissen, wurde die print
Anweisung in Funktion in Python geändert 3.0. Die formale Dokumentation ist in PEP 3105 und Motivation ist in Guido van Rossum E-Mail des .
Zu diesen Punkten würde Ich mag einen Kontrapunkt machen:
- Es gibt auch andere Operatoren wie
import
, die wir als eine Erklärung zu schreiben, obwohl ihre Funktionalität tatsächlich mit einer Funktion__import__
dupliziert- Für Anfänger, muss der Bediener
print
nicht die allgemeinen Anwendungslogik gehört. Für sie ist es der mysteriöse Operator, der ein Höhepunkt ihres Programms ist. Sie erwarten, dass es anders aussehen. - Alle Anfänger Bücher, die grundlegende Python 2.x wurden beschreiben jetzt garantiert vom ersten Beispiel , gebrochen werden. Sicherlich Sprachen manchmal ändern, aber diese Änderungen sind in der Regel weniger sichtbar zu Anfängern.
- Es ist nicht sofort offensichtlich für mich, dass eine Funktionalität von
print
auf Anwendungsebene dupliziert werden. Zum Beispiel, manchmal würde Ich mag Druck von einer Konsole als modales O Dialog umleiten. - Während die Menschen sagen, es ist schwer, alle
print
Aussagen auf eine Funktion neu zu schreiben, haben sie jeden Python 2.x Entwickler zu tun genau das für alle ihre Projekte gezwungen. Gut, es ist nicht schwer mit automatischem Konverter. - Jeder, der eine Fähigkeit genießt mit Funktion
print
zu manipulieren genauso gut bedient würde, wennprint
eine Aussage Umwicklungsfunktion__print__
ist.
- Für Anfänger, muss der Bediener
Wir können also bitte eine kanonische Antwort auf diese Frage auf den Seiten der Stack-Überlauf haben?
Lösung
Sieht mir wie du eine Debatte ist, keine Frage - sind Sie wirklich eine Antwort geht zu akzeptieren, die zeigt, wie tief und schlecht falsch Sie in Ihren Behauptungen waren
?!Auf zu Ihrem Debattierclub Punkte:
Es gibt auch andere Operatoren wie Import, die wir als eine Erklärung zu schreiben, obwohl ihre Funktionalität ist eigentlich dupliziert mit einer Funktion
__import__
Absolut falsch: function __import__
(wie alle andere Funktion - und Operator, was das betrifft) bindet nicht Namen im Rahmen der "Anrufer" (Code es enthält ) - any "thingie", deren Namen in dem "Anrufer scope" muss eine Aussage (wie Zuweisung, def
und call
) bindet. Ihr „Punkt“ erscheint völlig vermissen die extrem tief und entscheidenden Unterschied, dass Python zieht zwischen Aussagen und Ausdrücke - man vernünftigerweise Wenigsten diese Auszeichnung, aber Ignorieren ist es, die meisten offensichtlich, einfach falsch.
Python-Anweisungen sind Dinge, die Python-Compiler speziell bewusst sein müssen - sie die Bindung von Namen ändern können, können Steuerfluss verändern und / oder müssen möglicherweise ganz aus dem erzeugten Bytecode unter bestimmten Bedingungen entfernt werden (letzteres gilt assert
). print
war die nur Ausnahme von dieser Behauptung in Python 2; indem sie sie von der Liste von Aussagen zu entfernen, Python 3 entfernt eine Ausnahme macht die allgemeine Behauptung „hält gerade“, und deshalb ist eine reguläre Sprache. Sonderfälle nicht besondere genug sind, um die Regeln zu brechen ist seit langem ein Pythonic Lehre (do import this
an einem >>>
Prompt interaktiven Interpreter „die Zen of Python“ angezeigt, um zu sehen), und diese Änderung der Sprache entfernt eine Verletzung dieser Lehre, die seit vielen Jahren aufgrund einer frühen, fehlerhaften Design-Entscheidung.
Für Anfänger, der Bediener Druck tut nicht zur allgemeinen Anwendung gehören Logik. Für sie ist es die mysteriöse Operator, der eine Kulmination ihr Programm. Sie erwarten, dass es aussehen anders.
Die Aushärtung Anfänger ihrer Missverständnisse so früh wie möglich ist eine sehr gute Sache.
Die Anfänger Bücher Alles, was waren beschreibt grundlegende Python 2.x sind jetzt garantiert von der Faust gebrochen werden Beispiel. Sicherlich Sprachen manchmal ändert, aber Änderungen sind in der Regel weniger sichtbar Novizen.
Sprachen ändern selten in tiefer und rückwärts-inkompatible Weise (Python tut es etwa einmal pro Dekade) und einige Sprachfunktionen sind „gut sichtbar Novizen“, so dass die Gesamtzahl der Beobachtungen ist klein - und doch auch in diesem kleinen Kompass können wir leicht Gegenbeispiele, wo ein Feature gut sichtbar für Anfänger war gerade so schlecht konzipiert finden, dass es lohnt sich die Störung zu entfernen. Zum Beispiel Visual Basic moderne Dialekte Basic, wie Microsoft, nicht explizit vom Benutzer eingegebenen Zeilennummern verwenden, ein „Feature“, die beide schrecklich und gut sichtbar zu absolut jeder war, da es in der frühen Dialekten Grund obligatorisch war. Moderne Varianten von Lisp (von Schema ab) verwenden Sie kein dynamisches Scoping, eine misfeature, die leider sehr sichtbar war für Anfänger, im Grunde, sobald sie gestartet Funktionen in Lisp zu schreiben (in der Regel als schwer zu verstehen, Fehler in ihrem Code zu manifestieren) 1.5 (ich war einmal ein Anfänger in diesen und bezeugen kann, wie es mich gebissen schlecht).
Es ist nicht sofort offensichtlich für mich dass eine Funktionalität von Druck kann sein auf Anwendungsebene dupliziert. Zum Beispiel, manchmal würde Ich mag an Druck von einer Konsole als Redirect modal OS-Dialog.
Nicht sicher, ob ich diesem „Punkt“ folgen. Ändern Sie einfach sys.stdout
zu Ihrem Lieblings pseudo-Dateiobjekt und Umleitung nach Herzens contents - Sie haben die Option von Affe die eingebaute Funktion print
Patchen (die Sie nie 2 in Python hatte), aber niemand Arm ist verdreht und zwingt Sie, dies zu tun
Während die Menschen sagen, es ist schwer zu umschreiben Alle Druckanweisungen an eine Funktion, sie haben alle Python 2.x gezwungen Entwickler zu tun genau das für alle ihre Projekte. Gut, es ist nicht schwer mit automatischem Konverter.
Das 2to3
Werkzeug in der Tat nicht kümmern uns um alle so leicht Oberfläche Unverträglichkeiten - kein Schweiß (und es muss auf jeden Fall ausgeführt werden soll kümmern schon einige andere mehr print
, so dass die Leute es verwenden ausführlich). Also, was ist Ihr „Punkt“ hier?
Jeder, der eine Fähigkeit genießt mit Funktion Druck zu manipulieren wäre genauso gut bedient, wenn Druck ein war Anweisung Umwicklungsfunktion Drucken .
Eine solche Anordnung würde nicht per se entfernen unnötige Schlüsselwort (und vor allem, eine nicht gerechtfertigte Unregelmäßigkeit , wie ich oben erklärt: eine Aussage, die hat kein gut Grund zu sein eine Aussage, weil es absolut keine Notwendigkeit, dass die Compiler besonders bewusst, sie in irgendeiner Weise, Form oder Form zu sein!). Es ist weit von mir klar, dass eine zugrunde liegende Funktion hat, so einen wirklichen Mehrwert schaffen würde, aber wenn man reale Anwendungsfälle haben, können Sie sicher, den Fall in der Mailingliste Python-Ideen vorschlagen - eine solche Funktion verknüpft, wenn bewiesen wertvoll zu sein in der Tat werden, nachrüsten könnte durch die print
Anweisung in Python 2.7 sowie durch die print
Funktion in Python 3.2 verwendet werden.
Allerdings betrachten einen typischen Fall, in dem man wollen, könnte Affe-Patch, um die eingebauten in print
: Hinzufügen von Keyword-Argumente Phantasie Tweaks zu ermöglichen. Wie würden die __print__
Funktion, die Sie offenbar immer ge jene KW Argumente aus einer __print__
Erklärung vorgeschlagen? Einige funkier Syntax noch als die Schrecken des >> myfile
und die Hinter Komma ...?! Mit print
als Funktion folgen Schlüsselwort Argumente nur die ganz normalen und üblichen Regeln, die alle Funktion und Funktionsaufruf gelten - Glückseligkeit
So in der Zusammenfassung ist es mehr Pythonic für print
eine Funktion zu sein, weil es Anomalien, Sonderfälle entfernt, und keine Notwendigkeit für seltsame außergewöhnliche Syntax - Einfachheit, Regelmäßigkeit und Gleichmäßigkeit ist Pythons Marke
Andere Tipps
Hier ist der Grund, warum ich die print-Anweisung in 2.x. hate
>>> something()
<something instance at 0xdeadbeef>
>>> print something()
<something instance at 0xdeadbeef>
wertlos Objekt hat keine nützliche __str__
, Fein, ich umgehen kann, es betrachten einige mehr.
>>> dir(something())
['foo', 'bar', 'baz', 'wonderful']
>>> help(something().foo)
"foo(self, callable)"
hmm .. so macht, dass aufrufbar nehmen Argumente?
>>> something().foo(print)
something().foo(print)
^
SyntaxError: invalid syntax
>>> something().foo(lambda *args: print(*args))
something().foo(lambda *args: print(*args))
^
SyntaxError: invalid syntax
So ... Ich muss entweder eine Funktion definieren, zu verwenden,
>>> def myPrint(*args): print *args
def myPrint(*args): print *args
^
SyntaxError: invalid syntax
>>> def myPrint(*args): print args
...
>>> myPrint(1)
(1,)
Schauder oder Verwendung sys.stdout.write
, die fast so cludgy ist, da es sehr unterschiedliches Verhalten von print
hat. Es auch schaut unterschiedlich, was bedeutet, werde ich so gut wie nie vergessen, dass es existiert.
Mit print
Aussagen in einer kurzen, einmaligen Art Anlage und dann zu verbessern Protokollierung zu verwenden oder etwas besser ist, nur unelegant. Wenn der Druck wie diese Dinge funktioniert, und vor allem mit hohem Auftrag Funktionen verwendet werden könnte, dann wäre es besser, als nur die Sache verwenden Sie, wenn Sie mit nicht echten Protokollierung oder real Debugger.
Die print
Anweisung trägt auch die ungewöhnliche >>
Syntax für den Druck auf eine bestimmte Datei. Es gibt keine andere Anweisung in Python, die diese Syntax hat, so ist es ungewöhnlich, auf diese Weise.
Ich glaube, Sie aber richtig sind, könnten die meisten Probleme mit der print
Aussage durch die Einführung einer __print__
Funktion gelöst wurden.
fand ich GvR der „print ist die einzige Anwendung-Level-Funktionalität, die eine Aussage gewidmet hat“ überzeugend. Python ist eine allgemeine Sprache, und soll nicht eine Äußerung in einen Stream als Operator oder ein Schlüsselwort für die Ausgabe.
Es ist nicht Pythonic weil die Syntax sein sollte:
stdout.append("Hello World")
oder
stdout += "hello world"
Disclaimer:. Ich mag Python wirklich
Auf eine ernste Note ...
Ich denke, dass Python-Objektmodell und ‚es selbst implementieren‘ -Ansatz, um Dinge wie Attribut Sichtbarkeit groß ist. Ich denke, dass dies ‚alles ist ein Objekt‘ -Ansatz zur OOP, und auch die als eine Sammlung von Objekten Struktur definierten Objekte ist sehr klar bewusst.
Was ich Python fürchten tun wird ist eine Sprache geworden, die es nicht die Absichten in einer klaren Art und Weise, jedoch ist ... und ich würde es hassen, die Schönheit der Grundsätze sehen stecken Runter in Über denken die bereits unkonventionelle Syntax Präsentation . So ähnlich wie Lisp , schön in seiner Struktur, grimmig, imho in seiner Syntax.