Frage

Es gibt statische Analysetools für Python , aber kompilieren Zeit prüft den Laufzeitbindung Philosophie dass Python als Chance begreift. Es ist möglich , um den Standard-Python-Interpreter mit einem statischen Analyse-Tool zu wickeln einig „ zu erzwingen use strict "-ähnlichen Zwänge, aber wir haben keine weit verbreitete Annahme von so etwas sehen.

Gibt es etwas über Python, die „use strict“ Verhalten unnötig oder besonders unerwünscht?

macht

Als Alternative ist das "use strict" Verhalten unnötig in Perl, trotz seiner weit verbreiteten Annahme?

Hinweis: Mit „notwendig“ Ich meine „praktisch notwendig“, nicht unbedingt notwendig. Offensichtlich Sie können schreiben Perl ohne "use strict", aber (aus dem, was ich gesehen habe) die meisten Perl-Programmierer tun verwenden Sie es.

Hinweis: Der Python-Interpreter-Wrapper braucht nicht erforderlich "use strict" -ähnlichen Einschränkungen - Sie ähnlich eine pseudo-Pragma verwenden könnten "use strict", das durch den normalen Interpreter ignoriert werden würde . Ich spreche nicht über die Sprache-Level-Funktion hinzugefügt wird.


Update: Eine Erklärung, was "use strict" macht in Perl pro Kommentar. (Link zum offiziellen Dokumenten ist im ersten Absatz.)

Die „use strict“ Richtlinie hat drei verschiedene Komponenten, von denen nur zwei sind wirklich interessant:

  • strict vars verwenden: Statisch prüft lexikalisch variable Nutzung in Ihrem Programm scoped. (Beachten Sie, dass in Python gibt im Grunde nur global Umfang und local Umfang ist). Viele Python-Linters für diese Art der Sache überprüfen. Da es die einzige statische Analyse ist, dass sie tun können, nehmen die Linters Sie einfach lexikalischen Scoping verwenden und warnen Sie über Dinge, die in diesem Sinne falsch angezeigt, bis Sie ihnen sagen, den Mund zu halten; d.

    FOO = 12
    foo += 3
    

    Wenn Sie nicht etwas Besonderes mit Ihrem Namensraum tun dies nützlich sein kann für Fehler zu überprüfen.

  • use strict refs: Verhindert, dass symbolischen Namensraum dereferencing. Python engster Analog wird mit locals() und globals() symbolische Bindung und Identifikator-Lookup zu tun.

  • use strict subs: Keine realen analogen in Python

  • .
War es hilfreich?

Lösung

„die Laufzeitbindung Philosophie, dass Python umfasst ... macht‚use strict‘Verhalten unnötig [und] besonders unerwünscht“

Pretty gute Zusammenfassung. Danke.

Das ist es im Wesentlichen. Statische Analyse-Tools helfen Python nicht genug lohnen.


Bearbeiten

„Ich bitte für uns auf introspect warum wir brauchen es nicht und, in Verbindung stehend, warum Perl-Programmierer denken, dass sie es brauchen.“

Der Grund, warum genau der Grund ist, dass Sie bereits gab. Wir brauchen es nicht, weil es hilft nicht. Offensichtlich mögen Sie nicht, dass die Antwort, aber es gibt nicht viel mehr zu sagen. Kompilierung-oder Pre-Kompilierung Überprüfung einfach nicht helfen.

Da Sie jedoch die Zeit, um wieder die Frage gestellt, werde ich mehr Beweise für die Antwort geben Sie bereits gab.

Ich schreibe Java fast so viel wie ich Python schreiben. Java statische Typprüfung verhindert keine Logik Probleme; es nicht erleichtert Leistungsanforderungen erfüllen; es hilft nicht, die Fälle Anwendung zu erfüllen. Es ist nicht einmal das Volumen der Unit-Tests reduzieren.

Während statische Typprüfung des gelegentlichen Missbrauch einer Methode macht vor Ort, können Sie dies ebenso schnell in Python erfahren. In Python finden Sie es am Gerät zu testen Zeit, weil es nicht läuft. Hinweis: Ich sage nicht, falsche Arten mit vielen cleveren Unit-Tests gefunden werden, ich sage die meisten falschen Fragen werden durch nicht behandelte Ausnahmen gefunden, wo das Ding einfach nicht weit genug laufen zu bekommen Behauptungen zu testen

Der Grund, warum Pythonistas keine Zeit auf statische Überprüfung verschwenden ist einfach. Wir brauchen es nicht. Es bietet keinen Wert. Es ist eine Ebene der Analyse, die keinen wirtschaftlichen Nutzen hat. Es macht mir nicht mehr in der Lage, die wirklichen Probleme zu lösen, dass reale Menschen mit ihren realen Daten haben.

Schauen Sie sich die beliebtesten Fragen SO Python, die Sprache (nicht Problembereich oder Bibliothek) sind verwandt.

Gibt es einen Unterschied zwischen „foo ist None“und "foo == None" - == vs. is. Keine statische Prüfung kann dabei helfen. Siehe auch Gibt es einen Unterschied zwischen `==` und ` is` in Python?

Was bedeutet ** (Doppelstern) und * (Stern) zu tun für Parameter - *x gibt eine Liste, **x ein Wörterbuch gibt. Wenn Sie nicht wissen, Ihr Programm stirbt sofort, wenn Sie versuchen, etwas unpassend für diese Typen zu tun. „Was ist, wenn Ihr Programm nie etwas tut‚unangemessen‘“. Dann wird Ihr Programm funktioniert. ‚Nuff said.

Wie kann ich repräsentiere eine 'Enum' in Python - dies ist ein Plädoyer für eine Art von begrenzten Domain-Typ. Eine Klasse mit Klasse-Level-Werten macht ziemlich genau diesen Job. „Was passiert, wenn jemand die Zuordnung ändert“. Leicht zu bauen. Außer Kraft setzen __set__ eine Ausnahme zu erhöhen. Ja statische Überprüfung könnte dies erkennen. Nein, es geschieht nicht in der Praxis, dass jemand über eine Enumeration Konstante und eine Variablen verwechselt wird; und wenn sie es tun, ist es einfach, während der Laufzeit zu erkennen. „Was ist, wenn die Logik wird nie ausgeführt“. Nun, das ist schlechtes Design und schlechte Unit-Tests. einen Compiler-Fehler und setzt in der falschen Logik werfen, die nie getestet haben ist nicht besser als das, was in einer dynamischen Sprache geschieht, wenn es nie getestet wird.

Generator Expressions vs. Listenkomprehension - statische Prüfung nicht zu beheben hilft diese Frage.

Warum hat 1 +++ 2 = 3 -.. statische Überprüfung würde dies nicht vor Ort 1 +++ 2 in C legal ist perfekt trotz aller Compiler Überprüfung Es ist nicht die gleiche Sache in Python, wie es ist in C, aber genauso legal. Und genauso verwirrend.

Liste der Listen Änderungen reflektiert über Sublisten unerwartet - - Das ist ganz konzeptuell. Statische Prüfung kann entweder nicht helfen, dieses Problem zu lösen. Die Java-äquivalent wäre auch schlecht kompiliert und verhalten.

Andere Tipps

Nun, ich bin ein Python-Programmierer nicht viel, aber ich würde sagen, dass die Antwort ‚JA‘.

Jede dynamische Sprache, die Sie eine Variable mit einem beliebigen Namen jederzeit erstellen kann, könnten eine ‚strenge‘ Pragma verwenden.

Strenge Vars (eine der Optionen für strenge in Perl, ‚use strict‘ wendet sie alle auf einmal auf) in Perl verlangt, dass alle Variablen deklariert werden, bevor sie verwendet werden. Was bedeutet, dass dieser Code:

my $strict_is_good = 'foo';
$strict_iS_good .= 'COMPILE TIME FATAL ERROR';

Erzeugt einen schwerwiegenden Fehler bei der Kompilierung.

Ich weiß nicht, von einer Art und Weise Python erhalten diesen Code bei der Kompilierung abzulehnen:

strict_is_good = 'foo';
strict_iS_good += 'RUN TIME FATAL ERROR';

Sie erhalten eine Laufzeitausnahme erhalten, dass strict_iS_good nicht definiert ist. Aber nur, wenn der Code ausgeführt wird. Wenn Ihre Testsuite nicht zu 100% Deckung hat, können Sie einfach diesen Fehler versenden.

Jedes Mal, wenn ich in einer Sprache arbeiten, die dieses Verhalten nicht haben (PHP zum Beispiel), ich nervös. Ich bin keine perfekte Stenotypistin. Ein einfacher, aber schwer zu erkennen, Tippfehler können Ihren Code im Weg scheitern, die auf der Spur zu hart sein kann.

Also, zu wiederholen, YES Python könnte eine ‚strenge‘ Pragma verwenden, um auf der Kompilierung prüft, ob die Dinge zu machen, die bei der Kompilierung überprüft werden können. Ich kann mich nicht von irgendwelchen anderen Kontrollen hinzuzufügen, aber ein besserer Python-Programmierer könnte wahrscheinlich einige denkt.

Hinweis Ich konzentriere mich auf die pragmatische Wirkung von stict Vars in Perl, und bin polier einige Details über. Wenn Sie wirklich wissen wollen, alle Details finden Sie unter der Perldoc für strenge .

Update: Antworten zu einigen Anmerkungen

Jason Baker : Statische Prüfroutinen wie Pylint nützlich sind. Aber sie stellen einen zusätzlichen Schritt, und oft übersprungen werden kann. Der Aufbau einiger grundlegenden Kontrollen in die Compiler garantiert, dass diese Kontrollen konsequent durchgeführt werden. Wenn diese Überprüfungen durch einen Pragma steuerbar sind, auch die Einwand gegen die Kosten der Kontrollen in Bezug wird strittig.

popcnt : Ich weiß, dass Python eine Laufzeitausnahme generieren. Ich sagte so viel. Ich plädiere dafür, kompilieren Zeit, wo möglich, zu überprüfen. Bitte noch einmal lesen nur den Pfosten.

mpeters : Nein Computeranalyse von Code kann alle Fehler finden - dies entspricht das Halteproblem zu lösen. Schlimmer noch, um Fehler in Aufgaben, Compiler finden müßten Ihre Absichten kennen und finden Sie Orte, an denen Sie Ihre Absichten aus dem Code unterscheiden. Das ist ziemlich offensichtlich unmöglich.

Dies bedeutet jedoch nicht, dass keine Überprüfung durchgeführt werden sollte. Wenn es Klassen von Problemen sind, die leicht zu erkennen sind, dann macht es Sinn, zu stoppen sie.

Ich bin nicht vertraut genug mit Pylint und pychecker zu sagen, welche Klassen von Fehlern werden sie fangen. Wie gesagt bin ich mit Python sehr unerfahren.

Diese statischen Analyseprogramme sind nützlich. Ich glaube jedoch, dass, wenn sie die Fähigkeiten des Compilers zu vervielfältigen, zu den Compiler immer in der Lage sein werden, mehr über das Programm als jeden statischen Checker „wissen“ könnte. Es scheint verschwenderisch nicht diesen Vorteil zu nehmen Fehler zu reduzieren, wo möglich.

Update 2:

cdleary - In der Theorie stimme ich Sie, ein statischer Analysator jede Validierung tun, dass der Compiler kann. Und im Fall von Python, sollte es genug sein.

Allerdings, wenn Ihr Compiler komplex genug ist (vor allem, wenn Sie viele pragmas haben, die sich ändern, wie der Kompilierung auf, oder wenn wie Perl, Sie Code während der Kompilierung ausgeführt werden kann), dann muss der statische Analysator die Komplexität des Compilers nähern / Dolmetscher die Analyse zu tun.

Heh, all dieses Gerede von komplexen Compiler und Ausführen von Code während der Kompilierung zeigt meinen Perl Hintergrund.

Mein Verständnis ist, dass Python nicht pragmas hat und kann nicht von beliebigem Code während der Kompilierung ausgeführt werden. Also, wenn ich falsch bin oder diese Funktionen hinzugefügt werden, ein relativ einfachen Parser im statischen Analysator sollten ausreichen. Sicherlichwäre hilfreich, diese Kontrollen bei jeder Ausführung zu erzwingen. Natürlich, das ist die Art, wie ich tun würde, mit einem Pragma ist.

Wenn Sie Pragmas in den Mix, haben damit begonnen, Ihnen einen rutschigen Abhang hinunter und die Komplexität der Sie Analysator im Verhältnis zur Leistung wachsen muss und Flexibilität, die Sie in Ihrem pragmas bieten. Wenn Sie nicht vorsichtig sind, können Sie wie Perl aufzuwickeln, und dann „nur Python kann Python analysieren,“ eine Zukunft würde ich nicht sehen will.

Vielleicht wäre ein Kommandozeilenschalter ein besserer Weg gezwungen statische Analyse hinzuzufügen;)

(Keineswegs beabsichtigen Python die Fähigkeiten in Zweifel ziehen, wenn ich sage, dass es nicht mit der Kompilierung Verhalten wie Perl futz kann kann. Ich eine Ahnung haben, dass dies ein sorgfältig durchdachtes Design Entscheidung, und ich kann die Weisheit sehen in . es Perl extreme Flexibilität bei der Kompilierung ist, meiner Meinung nach, eine große Stärke und eine schreckliche Schwäche der Sprache,. ich die Weisheit in diesem Ansatz auch)

Python tut etwas, das Skript Syntax ändern können:

from __future__ import print_function

und verschiedene andere zukunfts Funktionen, die Syntax Auswirkungen haben. Es ist nur so, dass Python-Syntax strenger gewesen, stabileren und besser definierte als historische Perl; die Art von Dingen, die strenge Refs "und‚strenge subs‘verbieten noch nie in Python existiert hat.

‚strict vars‘ in erster Linie meine das stoppen, soll typoed Referenzen und verpassten-out‘vor versehentlichem Globals zu schaffen (na ja, Paketvariablen in Perl Begriffe). Dies kann nicht in Python passiert als bloße Zuordnungen standardmäßig lokale Deklaration und nackte unassigned Symbole in einer Ausnahme führen.

(Es ist immer noch der Fall, wenn Benutzer versehentlich versuchen, zu einem global schreiben Durch ohne es mit einer ‚globalen‘ Erklärung,, so dass entweder eine zufällige lokal oder, häufiger, ein UnboundLocalError. Dies führt dazu, ziemlich schnell gelernt werden wo, aber es ist ein arguable Fall mit zu Ihrem Einheimischen erklären helfen könnte. Obwohl nur wenige erfahrene Python-Programmierer die Lesbarkeit Belastung akzeptieren würde.)

Andere Sprache und Bibliothek Änderungen, die Syntax nicht betreffen, werden durch die Warnungen rel="noreferrer"> System .

Ich denke, es gibt einige Verwirrung, da das, was „use strict“ der Fall ist, aus den Kommentaren ich sehe. Es dreht sich nicht auf der Kompilierung Typprüfungen (sein wie Java). In diesem Sinne sind Perl progammers in Übereinstimmung mit Python-Programmierer. Wie S.Lott über diese Art von Kontrollen, sagt schützen nicht vor logischen Fehlern, nicht reduzieren die Anzahl der Unit-Tests müssen Sie schreiben, und wir sind auch keine großen Fans von Bondage-Programmierung.

Hier ist eine Liste von dem, was "use strict" tut tun:

  1. Mit symbolischen Referenzen ist ein Laufzeitfehler. Dies verhindert, dass Sie zu tun verrückt (aber manchmal nützliche Dinge wie)

    $var = 'foo';

    $foo = 'bar';

    print $$var; # this would contain the contents of $foo unless run under strict

  2. Mit dem nicht angemeldeten Variablen wird ein Laufzeitfehler (dies bedeutet, dass Sie verwenden müssen „mein“, „unser“ oder „local“ Ihren Variable Umfang zu erklären, bevor Sie es.

  3. Alle Barewords gelten als Kompilierung-Syntaxfehler. Barewords sind Wörter, die als Symbole oder Subroutinen nicht deklariert haben. Dies ist vor allem etwas ächten, die historisch getan wurde, aber wird als ein Fehler gewesen sein.

Python kein wahres lexikalisches Scoping hat, so streng Vars wäre nicht sehr sinnvoll sein. Es hat keine symbolische Referenzen AFAIK, so hat es nicht für strenge Refs müssen. Es hat nicht Barewords, so hat es keine Notwendigkeit einer strikten Vars.

Um ehrlich zu sein, es ist nur lexikalisches Scoping Ich vermisse. Die anderen beiden ich Warzen in Perl betrachten würde.

Diese ursprüngliche Antwort ist richtig, aber nicht erklären, vielleicht die Situation im praktischen Sinne.

  

Es existieren statische Analysetools für Python, aber kompilieren Zeitkontrollen sind in der Regel sein> diametral entgegengesetzt der Laufzeit-Bindung Philosophie, die Python als Chance begreift.

Was use strict "bietet in Perl ist die Fähigkeit, um sicherzustellen, dass ein falsch geschrieben oder Variablenname ist (in der Regel) zur Compile-Zeit gefangen. Dies tut Code verbessern Zuverlässigkeit, und beschleunigt die Entwicklung. Aber zu machen, um so etwas lohnt, Sie müssen Variablen deklarieren. Und Python-Stil scheint, dass zu entmutigen.

So in Python, die Sie nie über ein falsch geschrieben Variable herauszufinden, bis Sie merken, Laufzeit, dass die Zuordnung Sie dachten, Sie wird nicht gemacht wird, oder dass ein Ausdruck scheint auf einen unerwarteten Wert zu lösen. solche Fehler fangen kann zeitaufwendig, zumal Programme groß werden, und wie die Menschen gezwungen sind, zu halten Code entwickelt von anderen.

Java und C / C ++ es einen Schritt weiter, mit Typprüfung. Die Motivation ist praktisch, eher als philosophisch. Wie kann man so viele Fehler wie möglich fangen so schnell wie möglich, und sicher sein, dass Sie alle von ihnen zu beseitigen, bevor Code Produktion zu veröffentlichen? Jede Sprache scheint eine bestimmte Strategie zu nehmen und mit ihm laufen, basierend auf dem, was sie denken, ist wichtig. In einer Sprache wie Perl, wo Laufzeitbindung nicht unterstützt wird, macht es Sinn, den Vorteil von ‚strikter Anwendung‘ zu nehmen Entwicklung zu erleichtern.

Ich halte den 'use strict' in Perl eher wie ein Pragma, wie Sie angedeutet: es, das Verhalten des Compilers ändert.

Perl Sprache Philosophie unterscheidet sich von Python-Philosophie. Wie in, werden Sie mehr als genug Seil gegeben, sich immer wieder zu hängen, in Perl.

Larry Wall ist groß in der Linguistik, so haben wir von Perl, was als TIMTOWTDI bezeichnet wird (sagen tim-toe-dee) Prinzip gegen Zen of Python:

  

sollte es sein one-- und vorzugsweise   nur ein --obvious Weg, es zu tun.

Sie sehr leicht Pylint nutzen könnten und PyChecker mit Ihrem eigenen Geschmack von use strict für Python zu kommen (oder etwas analog zu perl -cw *scriptname*), sondern wegen der unterschiedlichen Philosophien in der Sprache Design, Sie werden es nicht weit in der Praxis begegnen.

Basierend auf Ihrem Kommentar zu dem ersten Plakate, sind Sie mit Python import this vertraut. Es gibt eine Menge Dinge in dort, die beleuchten, warum Sie nicht ein Äquivalent von use strict in Python sehen. Wenn Sie auf die meditieren koan in der Zen von Python gefunden, können Sie Erleuchtung für sich selbst finden. :)

Ich habe festgestellt, dass ich wirklich über Erkennung Verweise auf nicht angemeldeten Vars nur kümmern. Eclipse hat Pylint Integration über PyDev und obwohl Pylint bei weitem nicht perfekt, es macht einen vernünftigen Job dazu.

Es geht Art gegen Pythons dynamischer Natur, und ich habe #IGNOREs gelegentlich hinzuzufügen, wenn mein Code über etwas Gescheites bekommt. Aber ich finde, dass selten genug passiert, dass ich zufrieden bin.

Aber ich konnte die Nützlichkeit einiger Pylint-ähnliche Funktionalität verfügbar werden in Form einer Befehlszeilen Flagge sehen. Art wie Python 2.6 ist -3 Schalter, die Punkte der Inkompatibilität zwischen Python 2.x und 3.x-Code identifiziert.

Es ist sehr schwierig, große Programme zu schreiben, ohne ‚use strict‘ in Perl. Ohne ‚use strict‘, wenn Sie eine Variable wieder verwenden und falsch schreiben sie durch einen Brief aus verlassen, das Programm noch läuft. Und ohne Testfälle Ihre Ergebnisse zu überprüfen, können Sie nie solche Fehler finden. Es kann sehr zeitaufwendig sein, warum Sie falsche Ergebnisse aus diesem Grund bekommen.

Einige meiner Perl-Programme bestehen aus 5.000 Zeilen zu 10.000 Zeilen Code in Dutzende von Modulen gebrochen. Man kann nicht wirklich Produktionsprogrammierung tun, ohne ‚use strict‘. Ich würde nie Produktionscode erlauben, mit Sprachen in der Fabrik installiert werden, dass sie erzwingen nicht „Variablendeklarationen“.

Aus diesem Grund jetzt Perl 5.12.x hat das als Standardverhalten ‚use strict‘. Sie können sie ausschalten.

PHP hat mir schon einige Probleme gegeben, weil keine variable Erklärung Durchsetzung. So müssen Sie sich kleine Programme mit dieser Sprache zu begrenzen.

Nur eine Meinung ...

abcParsing

Perl ist eine hemmungslose Sprache, wie sie sagte :). So können Sie die Variable verwenden, bevor bekannt gegeben; Zum Beispiel: Wenn Sie einen var name „is_array“ verwenden, aber geben Sie in „is_arrby“, wird der Compiler Fehler melden nicht ohne „use strict“. Also, wenn langes Programm in Perl-Codierung, eine bessere Nutzung „use strict“ Aussage. Natürlich weniger als 50 Zeilen für einen Zeit-Skript ausgeführt wird, gibt es keine Notwendigkeit :)

Es scheint, wie das Ideal des „Pythonic“ Code dient eine Menge von dem gleichen Zweck wie use strict.

Ich habe keinen Hintergrund Perl, sondern von dem, was ich weiß, gibt es keine Funktion in Python, die für Ihren Code, um deaktiviert zu sein braucht „zuverlässigen“ zu sein, also in diesem Sinne, ich denke, kann man sagen, es ist nicht notwendig

scroll top