So beheben Sie Python-Einrückungen

264

Ich habe Python-Code mit inkonsistenten Einrückungen. Es gibt eine Menge Mischung aus Tabulatoren und Leerzeichen, um die Sache noch schlimmer zu machen, und selbst Leerzeicheneinrückungen bleiben nicht erhalten.

Der Code funktioniert wie erwartet, ist jedoch schwer zu pflegen.

Wie kann ich den Einzug korrigieren (wie HTML Tidy , aber für Python), ohne den Code zu beschädigen?

Shay Erlichmen
quelle
Können Sie diesen Link überprüfen und Ihre Eingaben zur Verwendung des reindent.py-Moduls bereitstellen
user1050619
Wie unten von @ andy-hayden erwähnt, schauen Sie sich diese verwandte Frage an - autopep8bietet im Grunde Einrückungen und vieles mehr: stackoverflow.com/questions/14328406/…
Pierz
2
Dies ist eine wahnsinnig nützliche Frage, die ich ziemlich oft machen muss. Es geht nicht darum, ein Tool zu empfehlen, sondern darum, wie es geht.
Andy Hayden

Antworten:

282

Verwenden Sie das reindent.pySkript, das Sie im Tools/scripts/Verzeichnis Ihrer Python-Installation finden:

Ändern Sie Python-Dateien (.py) so, dass Einrückungen mit 4 Leerzeichen und keine Zeichen auf harten Tabulatoren verwendet werden. Schneiden Sie auch überschüssige Leerzeichen und Tabulatoren an den Zeilenenden ab und entfernen Sie leere Zeilen am Ende der Dateien. Stellen Sie außerdem sicher, dass die letzte Zeile mit einer neuen Zeile endet.

In diesem Skript finden Sie detaillierte Anweisungen zur Verwendung.

Alex Martelli
quelle
51
Leider ist es nicht Teil der normalen Python-Installation unter Debian und Ubuntu. Es ist in das python-examplesPaket aufgeteilt.
Ephemient
16
Ausgezeichnet! Alles, was Debian- und Ubuntu-Benutzer tun müssen, ist, dieses Paket zu erhalten. Alternativ befindet sich das Skript auch unter svn.python.org/view/python/trunk/Tools/scripts/… .
Alex Martelli
9
@ Shay Erlichmen: Versuchen Sie "python -tt yourscript.py"
nosklo
8
Fedora / RedHat / CentOS-Benutzer sollten das Paket "python-tools" installieren.
Cristian Ciupitu
26
Nur um den Kommentar von Ephemient zu ergänzen: Sobald er python-examplesinstalliert ist, finden Sie reindent in /usr/share/doc/pythonX.X/examples/Tools/scripts/reindent.py.
Larry Hastings
59

Wenn Sie Vim verwenden , lesen Sie :h retab.

                                                        *: ret * *: retab *
: [range] ret [ab] [!] [new_tabstop]
                        Ersetzen Sie alle Sequenzen von Leerzeichen, die a enthalten
                        <Tab> mit neuen Leerzeichenfolgen unter Verwendung der neuen
                        Tabstop-Wert angegeben. Wenn Sie keine neue angeben
                        Tabstop-Größe oder Null, Vim verwendet den aktuellen Wert
                        von 'tabstop'.
                        Der aktuelle Wert von 'tabstop' wird immer verwendet
                        Berechnen Sie die Breite der vorhandenen Registerkarten.
                        Mit! Ersetzt Vim auch nur normale Zeichenfolgen
                        Leerzeichen mit Tabulatoren, falls zutreffend.
                        Wenn 'expandtab' aktiviert ist, ersetzt Vim alle Registerkarten durch die
                        angemessene Anzahl von Leerzeichen.
                        Dieser Befehl setzt 'tabstop' auf den neuen angegebenen Wert.
                        und wenn es für die gesamte Datei ausgeführt wird, was Standard ist,
                        sollte keine sichtbare Änderung vornehmen.
                        Achtung: Dieser Befehl ändert alle <Tab> -Zeichen
                        innerhalb von Strings in einem C-Programm. Verwenden Sie "\ t", um dies zu vermeiden
                        das (das ist sowieso eine gute Angewohnheit).
                        ": retab!" kann auch eine Folge von Leerzeichen durch ändern
                        <Tab> -Zeichen, die ein printf () durcheinander bringen können.
                        {nicht in Vi}
                        Nicht verfügbar, wenn | + ex_extra | Funktion wurde bei deaktiviert
                        Kompilierzeit.

Zum Beispiel, wenn Sie einfach eingeben

: ret

Alle Ihre Registerkarten werden zu Leerzeichen erweitert.

Du möchtest vielleicht

: se et "Abkürzung für: set expandtab

um sicherzustellen, dass in neuen Zeilen keine Literal-Tabulatoren verwendet werden.


Wenn Sie Vim nicht verwenden,

perl -i.bak -pe "s / \ t / '' x (8-pos ()% 8) / zB" file.py "

Ersetzt Tabulatoren durch Leerzeichen, vorausgesetzt, Tabulatoren werden alle 8 Zeichen angehalten file.py(wobei das Original für alle file.py.bakFälle verwendet wird). Ersetzen Sie die 8s durch 4s, wenn Ihre Tabulatoren stattdessen alle 4 Leerzeichen stehen.

kurzlebig
quelle
2
Gut gearbeitet. Dies ist der einfachste Weg, um die Verwechslung von Tab-Einrückungen zu beheben.
Srikant
Sicher nicht der einfachste Weg.
CONvid19
52

Ich würde nach autopep8 greifen , um dies zu tun:

$ # see what changes it would make
$ autopep8 path/to/file.py --select=E101,E121 --diff

$ # make these changes
$ autopep8 path/to/file.py --select=E101,E121 --in-place

Hinweis: E101 und E121 sind pep8-Einrückungen (ich denke, Sie können einfach übergeben --select=E1, um alle Einrückungsprobleme zu beheben - diejenigen, die mit E1 beginnen).

Sie können dies mit dem rekursiven Flag auf Ihr gesamtes Projekt anwenden:

$ autopep8 package_dir --recursive --select=E101,E121 --in-place

Siehe auch Tool zum Konvertieren von Python-Code in PEP8-kompatibel .

Andy Hayden
quelle
Das ist großartig ... Ich habe nach einem Tool wie Rubys Rubocop für Python
gesucht
1
autopep8schlägt fehl, wenn die Syntax falsch ist. Sie können dies mitpython -tt <file.py>
Nishant
47

autopep8 -i script.py

Verwenden Sie autopep8

autopep8 Formatiert Python-Code automatisch so , dass er dem PEP 8 nullstyleHandbuch entspricht. Mithilfe des pep8Dienstprogramms wird bestimmt, welche Teile der nullcodeFormatierung formatiert werden müssen. autopep8ist in der Lage, die meisten nullformattingProbleme zu beheben, die von gemeldet werden können pep8.

pip install autopep8
autopep8 script.py    # print only
autopep8 -i script.py # write file
CONvid19
quelle
Ich habe nur einen Zeilencode mit "Import OS" und 4 Leerzeichen davor, aber es wird nicht eingerückt ... ein Grund warum
pkm
3
@pkm 4 Leerzeichen (oder jede Einrückung, die ein Vielfaches von 4 ist) ist Teil des PEP8
rbaleksandar
13

Mit Vim sollte es nicht mehr involviert sein als zu schlagen Escund dann zu tippen ...

:%s/\t/    /g

... in der Datei, die Sie ändern möchten. Dadurch werden alle Tabulatoren in vier Leerzeichen konvertiert. Wenn Sie auch inkonsistente Abstände haben, wird dies schwieriger.

Ben Hughes
quelle
11
Können Sie die ursprünglichen Codierer aufspüren und erweiterte Abfragetechniken anwenden? Es gibt nichts Schlimmeres als inkonsistent eingerückten Code.
Ben Hughes
3
@ Ben Die inkonsistente Einrückung ist das geringste unserer Probleme von diesem Kerl :)
Shay Erlichmen
9

Es gibt auch PythonTidy (da Sie sagten, dass Sie HTML Tidy mögen).

Es kann jedoch viel mehr als nur Tabs bereinigen. Wenn Sie so etwas mögen, ist es einen Blick wert.

Paul Hildebrandt
quelle
5

Auf den meisten UNIX-ähnlichen Systemen können Sie außerdem Folgendes ausführen:

expand -t4 oldfilename.py > newfilename.py

Ändern Sie in der Befehlszeile die Nummer, wenn Sie Tabulatoren durch eine andere Anzahl von Leerzeichen als 4 ersetzen möchten. Sie können einfach ein Shell-Skript schreiben, um dies mit einer Reihe von Dateien gleichzeitig zu tun, wobei die ursprünglichen Dateinamen beibehalten werden.

Crowman
quelle
1
Beachten Sie, dass die Verwendung derselben Datei nicht funktioniert und Sie eine leere Datei erhalten. Diese Antwort funktioniert jedoch tatsächlich und ich verwende sie, wenn ich meine Tabulatoren in Leerzeichen konvertieren muss. Könnte jemand die Ablehnung erklären? Ich werde es +1 erhöhen.
S. Kerdel
Gibt es eine Möglichkeit, die überschriebene Datei wiederherzustellen? Nur verwendet , um das obige Verfahren und der Wert meines Tages des Code verschwunden facepalm . Danke
Simas
4

Wenn Sie faul sind (wie ich), können Sie auch eine Testversion von Wingware Python IDE herunterladen, die über ein Auto-Fix-Tool für fehlerhafte Einrückungen verfügt. Es funktioniert ziemlich gut. http://www.wingware.com/

Yansky
quelle
4

Das reindent-Skript hat bei mir aufgrund eines fehlenden Moduls nicht funktioniert. Wie auch immer, ich habe diesen sedBefehl gefunden, der den Job perfekt für mich macht:

sed -r 's/^([  ]*)([^ ])/\1\1\2/' file.py
Martin Vegter
quelle
2
Illegale Optionen -r.
HelloWorld
2

Versuchen Sie Emacs. Es bietet eine gute Unterstützung für Einrückungen, die in Python benötigt werden. Bitte überprüfen Sie diesen Link http://python.about.com/b/2007/09/24/emacs-tips-for-python-programmers.htm

Arnkrishn
quelle
2
python-Modus ist schön Python zu schreiben, aber nichts an der Verbindung beschreibt , wie fix in einer bestehenden Datei Einzug.
Ephemient
5
Mx untabify verwandelt Tabs in Emacs in Leerzeichen
Paul Hildebrandt
Die Verbindung ist (effektiv) unterbrochen. Es wird auf eine Seite mit dem Titel "C-Programmiersprache für Anfänger" (!) Weitergeleitet .
Peter Mortensen
1

Versuchen Sie IDLE und verwenden Sie Alt+ X, um Einrückungen zu finden.

anshuman
quelle
0

Ich habe eine einfache Lösung für dieses Problem. Sie können zuerst ": retab" und dann ": retab!" Eingeben, dann wäre alles in Ordnung

Hanqiang
quelle
1
Geben Sie " :retab" in welchem ​​Kontext ein. In Vim ?
Peter Mortensen