Einrückung in Python - Lösungsoption

Wenn Sie in den meisten Sprachen alle Einrückungen im gesamten Quellcode des Programms entfernen und dann die automatische Formatierung anwenden, bleibt das Programm voll funktionsfähig und wird gleichzeitig im gleichen Stil entworfen.

Es scheint, dass im Fall von Python eine solche Operation nicht möglich ist.

Zumindest konnte ich nirgendwo finden, wie ich zufällig versetzte Einrückungen in Python sofort erkennen kann. Ich musste dieses Problem selbst lösen.


Einführung


Lieber Leser!
Wenn die Aussage in Ihrer Nähe ist:
1) Diese Programmierung ist eine hohe Kunst.
2) Wenn Sie in einer beliebigen Sprache programmieren, müssen Sie die Leistung und Vielfalt dieser Sprache optimal nutzen, um den Quellcode zu minimieren.
3) Wenn Sie programmieren, müssen Sie Ihr hohes Niveau im Quellcode des Programms anzeigen, damit niemand über Ihr Programm sagen kann, dass es "dumm" ist.

Wenn mindestens einer (!) Der oben genannten Punkte in Ihrer Nähe ist, lesen Sie diesen Artikel bitte nicht! Bitte verschwenden Sie keine Zeit damit.
Es wird über einen völlig weit hergeholten und absurden Moment der Programmierung sprechen.

Lieber Leser!
Wenn die Aussage bereits in Ihrer Nähe ist:
1) Diese Programmierung ist eine routinemäßige, ziemlich eintönige Aufgabe, genau wie das Graben eines endlosen gewundenen Grabens.
2) Wenn Sie in einer beliebigen Sprache programmieren, müssen Sie einen bestimmten minimal optimalen Satz von Sprachbefehlen verwenden (möglicherweise werden die meisten Befehle gelöscht), damit selbst ein Junior-Programmierer Ihr Programm leicht herausfinden kann!
3) Das sollte beim Programmieren Ihres Programms bis zu einem gewissen Grad "dumm" sein. Nachdem Sie es implementiert haben, können Sie ein neues Projekt starten und den Junior-Programmierer, der an dem Projekt teilgenommen hat, ruhig einsetzen, um es unter den regelmäßig kleinen neuen Anforderungen des Kunden zu unterstützen und zu verfeinern.

Wenn all diese drei obigen Aussagen für Sie zutreffen, haben Sie vielleicht ein Problem, dessen Lösung ich anbieten möchte.

Die Hauptnachteile von Python:

1) Python wird bei der Verwendung von Ressourcen und ihren Daten "nicht minimiert" und eignet sich daher nicht zum Schreiben von Programmen, die eine Ressourcennutzung erfordern, wie mobile Anwendungen, Programme auf niedriger Ebene (Treiber, residente Programme usw.). .) usw.

2) Python ist langsam und Single-Threaded (GIL - Global Interpreter Lock).

3) In Python basieren Programmblöcke NUR (!) Auf Einrückungen. Deswegen:

  • Die „Lesbarkeit“ von Programmen nimmt ab (siehe unten).
  • Eine vollständige automatische Formatierung des Quelltextes ist nicht möglich.
  • Es besteht die Wahrscheinlichkeit, dass ein Fehler bei einem versehentlichen und unbemerkten Versatz von Einrückungen auftritt, der manchmal sehr schwer zu finden und zu korrigieren ist.

Der erste Nachteil von Python ist schwer zu beseitigen, und hier gibt es nur eine Einschränkung im Umfang seiner Verwendung. Aber das ist ein natürlicher Moment, weil Es ist unmöglich, eine Sprache zu finden, die in allen Bereichen der Aufgaben am effektivsten ist.

Der zweite Nachteil von Python ist die hervorragende bidirektionale Interoperabilität mit C / C ++.

Oft entwickelt sich ein erfolgreiches Projekt ziemlich schnell. Zunächst gibt es keine hohen Leistungsanforderungen, und in Python werden bei Bedarf winzige Einfügungen in C / C ++ verwendet.
Mit der Entwicklung und Erweiterung des Projekts steigen jedoch die Leistungsanforderungen entsprechend, und Python erfüllt immer häufiger die Funktionen der aufgerufenen Sprache aus C / C ++. Gleichzeitig nimmt die Rolle von Python selbst nicht ab, da Wenn Sie Abschnitte programmieren, die keine hohe Ausführungsgeschwindigkeit erfordern (und in großen Projekten normalerweise ziemlich viele davon), ist Python ein praktischeres Werkzeug als C / C ++.

Und für den dritten Nachteil von Python möchte ich meine eigene Lösung anbieten.

Sie alle wissen, dass für die überwiegende Mehrheit der Sprachen das automatische Format des Quelltextes sehr häufig verwendet wird.

Jene. Unabhängig davon, welche Einrückung ein Programm in dieser Sprache geschrieben hat, werden alle Einrückungen in die Standardform gebracht, wenn Sie mit der automatischen Formatierung beginnen. Für Python scheint dies unmöglich.

Jeder Programmierer, der Projekte in mehreren tausend Zeilen der Sprache geschrieben hat, weiß, dass der Entwicklungsprozess nicht nur den nächsten Teil des Programms erfindet und ausfüllt, sondern ständig Abschnitte des Codes in das Unterprogramm verschiebt, jetzt zwischen den Programmblöcken, dann in gemeinsame externe Module usw. P.

Darüber hinaus beginnen Benutzer / Kunden, die sich bereits in der Anfangsphase befinden und mit dem ersten Entwurf des Programms gearbeitet haben, in der Praxis, die Aufgaben des endgültigen Projekts zu ändern und zu ergänzen, was zu einer starken Anpassung des Quellcodes führt.

Und dann lohnt es sich in Python, im Falle einer signifikanten Änderung von Dutzenden von Teilen des (!) Programms eines anderen (oder Ihres eigenen, aber an die Sie sich überhaupt nicht erinnern), beim Übertragen eines Blocks versehentlich einen zusätzlichen Code zu fangen, der zu einem anderen Block gehört, das Programm möglicherweise voll funktionsfähig zu bleiben. Der Algorithmus seiner Arbeit ändert sich jedoch (lesen Sie "Das Programm beginnt falsch zu arbeiten"), und es ist manchmal sehr schwierig, die Stelle eines solchen Fehlers im Programm eines anderen zu finden und dann die Einrückung korrekt wiederherzustellen!

In diesem Fall können Sie sich natürlich den Quelltext (vor den Änderungen) ansehen, aber wenn Sie an dieser Stelle bereits viele Korrekturen vorgenommen haben, müssen Sie diese gesamte Korrekturkette „abwickeln“.

Lösen des Einrückungsproblems in Python


Der Einzug in Python wird durch die folgenden Befehle gebildet:

- class
- def

- for
- while

- if

- try

- with

Und um die Abhängigkeit von Einrückungen zu beseitigen, habe ich beschlossen, für jeden dieser Befehle den Befehl „final“ zu verwenden, der den Befehlsblock definitiv schließt (Einrückung).

Klassen- und Def-Befehle


Bei Klassen- / Def-Befehlen gibt es normalerweise kein Problem beim Ausfüllen des Einrückungsblocks Der Block wird mit dem neuen Befehl class / def geschlossen.

Der einzige Fall ist das Vorhandensein eines oder mehrerer Unterprogramme, die in einem anderen Unterprogramm / einer anderen Methode deklariert sind.

def ppg_1():
    def ppg_2():
        ...  ppg_2 ...
    def ppg_3():
        ...  ppg_3 ...
        ...  ppg_3 ...
        ...  ppg_3 ...
    ...  ppg_1 ...

Wenn Sie dann versehentlich den Anweisungsblock des letzten internen Unterprogramms verschieben, wird er mit den Befehlen des Unterprogramms / der Methode zusammengeführt, in dem dieses interne Unterprogramm deklariert ist.

def ppg_1():
    def ppg_2():
        ...  ppg_2 ...
    def ppg_3():
        ...  ppg_3 ...
    ...  ppg_3 ...
    ...  ppg_3 ...
    ...  ppg_1 ...

In diesem Fall müssen Sie am Ende dieser internen Routine / Methode nur "return" setzen, was das Ende des Blocks seiner Befehle deutlich anzeigt.

def ppg_1():
    def ppg_2():
        ...  ppg_2 ...
    def ppg_3():
        ...  ppg_3 ...
        ...  ppg_3 ...
        ...  ppg_3 ...
        return
    ...  ppg_1 ...

Die for- und while-Befehle


Am Ende der Anweisungen "for" und "while" müssen Sie "continue" setzen.

Jene. Der Befehl sieht folgendermaßen aus:

for  <...> :             #  
    ...  ....
    continue             #  

und

while  <...> :           #  
    ...  ....
    continue             #  

Zum Beispiel:
        ...  ...

        for i in range(10):
            ...  for ...

            ...  for  ...

            ...  for  ...

        ...  ...

Das versehentliche Löschen der Einrückung in den letzten Befehlen des "for" -Blocks führt nicht zu einem Programmausführungsfehler, sondern zu fehlerhaften Ergebnissen! Und es ist sehr schwierig, einen solchen Fehler zu finden, wenn Sie den Algorithmus des Programms nicht kennen (z. B. wenn es sich um das Programm eines pensionierten Kollegen handelt)!

Hier ist wie:
        ...  ...

        for i in range(10):
            ...  for ...

        ...  for  ...

        ...  for  ...

        ...  ...

Im folgenden Beispiel wird beim versehentlichen Löschen des Einzugs sofort ein Fehler ausgegeben:
        ...  ...

        for i in range(10):
            ...  for ...

            ...  for  ...

            ...  for  ...

            continue

        ...  ...

Wenn Befehl


Am Ende der "if" -Anweisung müssen Sie den Befehl "elif 0: pass" eingeben und anstelle von "else" den Befehl "elif 1:" verwenden.

Jene. für "if" gibt es einen vollständigen Befehlsblock:

if <>                      #  
    ...  ....
elif <>
    ...  ....
elif 1:                    #  "else"
    ...  ....
elif 0: pass               #  

Zum Beispiel:
        ...  ...

        if  result != -1 :

            ...  if ...

            ...  if ...

            ...  if ...

        elif 0: pass

        ...  ...

Wenn Sie es wie oben gezeigt machen, erzeugt der Einzug im Befehlsblock "if ... elif 0: pass" einen Startfehler.

Wenn dann ohne "elif 0: pass" die Einrückungen in den letzten Zeilen des "if" -Blocks versehentlich gelöscht werden, suchen Sie zuerst nach der Stelle, an der das Programm falsch funktioniert hat, und überlegen dann, welche Einrückungen im Block und welche enthalten sein sollten - Nein.
        ...  ...

        if  result != -1 :

            ...  if ...

        ...  if ...

        ...  if ...

        ...  ...

Warum sonst ist es meiner Meinung nach ratsam, die von den Operatoren erstellten Befehlsblöcke "für",
"während", "wenn" usw. zu schließen,

denn wenn Sie sich einen Codeabschnitt ansehen, in dem es einen großen Unterschied in der
Einrückungsstufe zwischen dem Ende des Stroms gibt Block und der Anfang des nächsten, können Sie oft nicht mehr verstehen, welche Einrückung zu was gehört.

Dann können Sie mit den Konstruktionen mit "continue" und "elif 0: pass" nicht nur vor versehentlichem Löschen schützen, sondern auch angeben, mit welchem ​​Block Sie begonnen haben, und einen Kommentar dazu schreiben .

Zum Beispiel sehen Sie das Ende eines großen Blocks:

                            ...  ...

                            ...  ...

                            ...  ...

                            ...  ...

                        ...  ...

                        ...  ...

                        ...  ...

                        ...  ...

    elif result == 1 :

        ...  ...

        ...  ...

        ...  ...

        ...  ...

Und es ist schwer zu merken, was jede Einrückungsstufe bedeutet.

Aber es ist viel einfacher, wenn es so aussieht:

                            ...  ...

                            ...  ...

                            ...  ...

                            ...  ...

                            continue    #   b'\\r\\n'   

                        ...  ...

                        ...  ...

                        ...  ...

                        ...  ...

                    elif 0: pass     #  " "  " "

                elif 0: pass         #   . - 

                continue             #    

            continue                 #  .,  -  " "
                      
    elif result == 1 :

        ...  ...

        ...  ...

        ...  ...

        ...  ...

Versuchen Sie den Befehl


Es gibt eine vollständige Analogie zu "wenn".

try:                   #  
    ...  ....
except <...>:
    ...  ....
except 1:              #  "else"
    ...  ....
except 0: pass         #  

Das einzige Problem ist der Befehl finally : . Danach können Sie keinen der Befehle des aktuellen Try-Blocks mehr eingeben.

Wenn Sie es verwenden müssen, müssen Sie den gesamten Befehlsblock nach "finally:" im lokalen Unterprogramm entfernen (dh als Unterprogramm innerhalb des aktuellen Unterprogramms deklarieren), um die Möglichkeit der automatischen Formatierung und des Schutzes vor versehentlichem Löschen von Einrückungen zu erhalten.

Jene. Der Text mit "finally:" sieht folgendermaßen aus:

    def my_ppg():
        ...
        return

    ...

    finally:
        my_ppg()

    ...

In diesem Fall können Sie auch die automatische Formatierung sicher anwenden und haben keine Angst davor,
versehentlich Einrückungen zu löschen.

Befehl "Mit"


In Python gibt es keine zusätzlichen Befehle für "with", die als Ende eines Blocks dienen könnten. Daher ist die Situation mit ähnlich der Situation mit schließlich.
Jene. Entweder übertragen wir alle Befehle, die im Anweisungsblock "with" ausgeführt werden, in die lokale Unterroutine, oder ... Aber dann sage ich eine schrecklich blasphemische Sache: "... oder Sie müssen sie einfach nicht verwenden."

Tatsache ist, dass "mit" einerseits nur ein "Wrapper" für vorhandene Python-Befehle ist (das heißt, Sie können ihn jederzeit durch einen ähnlichen Satz von Befehlen ersetzen), andererseits hat die Praxis gezeigt, dass für Junior-Programmierer dieser Kontext Der Manager ist schwer für die volle Entwicklung. Wenn Sie also möchten, dass ein Junior-Programmierer das implementierte Projekt nach Ihnen ruhig begleitet, müssen Sie keine Teams in dem Projekt einsetzen, die seine Arbeit behindern.

Fazit



Ich denke, Sie haben bereits verstanden, dass es ziemlich einfach ist, ein VOLL AUTO FORMATTING eines solchen Programms zu schreiben, wenn Sie ein Programm in Python mit ANYWHERE (!) Von den oben genannten Techniken zum Erstellen von Einrückungsblöcken schreiben Für alle Befehlsblöcke gibt es einen Anfang und ein Ende des Blocks, unabhängig von der Einrückung.

Mit einem Lächeln stellen wir nun die Frage wie folgt: „Was sind die Nachteile von Python, wenn Sie Einrückungsblöcke korrekt formatieren, bei Bedarf mit C / C ++ interagieren und Python nicht in mobilen und ressourcenkritischen Anwendungen verwenden?“

Antwort: „Nur kleinere Mängel. Jene. im Großen und Ganzen - nein. "

Und mit einer solchen Formulierung der Frage können wir nur die Hauptvorteile von Python genießen.

  1. Einfachheit.
  2. Minimaler Testzyklus von Websites: geschrieben-gestartet-geprüft.
  3. Power - Bibliotheken / Frameworks für Python sind "für jeden Geschmack und jede Farbe".

Diese drei Vorteile zusammen ergeben meiner Meinung nach eine nahezu perfekte Version der Sprache (vergessen Sie nicht, dass dies nur den in der obigen Frage angegebenen Bedingungen unterliegt!).

All Articles