Narzędzie do konwersji kodu Pythona na zgodny z PEP8

113

Wiem, że istnieją narzędzia, które sprawdzają, czy Twój kod w Pythonie jest zgodny z PEP8, na przykład istnieje zarówno usługa online, jak i moduł Pythona .

Jednak nie mogę znaleźć usługi lub modułu, który może przekonwertować mój plik Pythona na samodzielny, prawidłowy plik Pythona PEP8. Czy ktoś wie, czy są jakieś?
Zakładam, że jest to wykonalne, ponieważ w PEP8 chodzi o wygląd kodu, prawda?

Chen Xie
źródło
1
Myślę, że nie ma żadnego narzędzia, które konwertuje kod na kod zgodny z PEP8. PEP8 zawierał również reguły nazewnictwa zmiennych, więc jeśli takie narzędzie istnieje, zmieni również nazwy twoich zmiennych i możesz wtedy nie być w stanie zrozumieć własnego kodu.
Ashwini Chaudhary
1
@AshwiniChaudhary To dobra uwaga, warto również wspomnieć, że zmiana nazw zmiennych może wpłynąć na inne osoby już używające Twojego kodu, jako że nie zawsze jest to dobry pomysł. (autopep8 tego nie robi.)
Andy Hayden

Odpowiedzi:

38

Niestety "burza pep8" (cały projekt) ma kilka negatywnych skutków ubocznych:

  • wiele konfliktów podczas łączenia
  • złamać winę
  • utrudniać przeglądanie kodu

Jako alternatywę (i dzięki @yp za pomysł ) napisałem mały pakiet, który autopep8 obsługuje tylko te linie, nad którymi pracowałeś od ostatniego zatwierdzenia / gałęzi:

Zasadniczo pozostawiając projekt trochę lepiej niż go znalazłeś :

pip install pep8radius

Załóżmy, że skończyłeś pracę masteri jesteś gotowy do wykonania:

# be somewhere in your project directory
# see the diff with pep, see the changes you've made since master
pep8radius master --diff
# make those changes
pep8radius master --diff --in-place

Lub, aby wyczyścić nowe wiersze, które zatwierdziłeś od ostatniego zatwierdzenia:

pep8radius --diff
pep8radius --diff --in-place

# the lines which changed since a specific commit `git diff 98f51f`
pep8radius 98f51f --diff

Zasadniczo pep8radiusstosuje autopep8 do wierszy w wyjściu git / hg diff (z ostatniego wspólnego zatwierdzenia ).

Ten skrypt obecnie działa z git i hg, jeśli używasz czegoś innego i chcesz, aby to zadziałało, napisz komentarz / problem / PR !

Andy Hayden
źródło
2
+1 bardzo dobra inicjatywa ... zastanawiam się, jak zrobić wtyczkę Notepad ++ w tym samym celu ... ponieważ to mój ulubiony edytor w systemie Windows
kmonsoor
1
@kmonsoor dobry pomysł, nie myślałem o wtyczkach edytora! Daj mi znać na githubie w jakikolwiek sposób, w jaki mogę pomóc / ułatwić korzystanie z niego poza CLI ... Przewiduję kilka (do rozwiązania) problemów.
Andy Hayden
tutaj znalazłem interesującą listę wtyczek do edytorów github.com/jcrocholl/pep8/wiki/RelatedTools , choć nie ma szczęścia dla Notepad ++ ...
kmonsoor
1
Właśnie stworzyłem skrypt łączący Notepad ++ i Autopep8 w oparciu o inną wtyczkę "Python Script". Jednak to działa. Plz sprawdź tutaj: bit.ly/pep8_tonizer
kmonsoor
185

Możesz użyć autopep8 ! Podczas gdy ty robisz sobie filiżankę kawy, to narzędzie szczęśliwie usuwa wszystkie brzydkie naruszenia PEP8, które nie zmieniają znaczenia kodu.

Zainstaluj go przez pip:

pip install autopep8

Zastosuj to do określonego pliku:

autopep8 py_file --in-place

lub do twojego projektu (rekurencyjnie), opcja szczegółowa daje ci informację zwrotną, jak to idzie :

autopep8 project_dir --recursive --in-place --pep8-passes 2000 --verbose

Uwaga: czasami domyślne 100 przebiegów nie wystarcza, ustawiam go na 2000, ponieważ jest dość wysoki i złapie wszystkie oprócz najbardziej kłopotliwych plików (przestaje przekazywać, gdy nie znajdzie rozwiązalnych wykroczeń pep8) ...

W tym momencie sugeruję ponowne przetestowanie i wykonanie zatwierdzenia!

Jeśli chcesz "pełnej" zgodności z PEP8: jedną z taktyk, których użyłem, jest uruchomienie autopep8 jak powyżej, a następnie uruchomienie PEP8, który wypisuje pozostałe naruszenia (plik, numer linii i co):

pep8 project_dir --ignore=E501

i ręcznie zmieniaj je indywidualnie (np. E712s - porównanie z wartością logiczną).

Uwaga: autopep8 oferuje --aggressiveargument (w celu bezwzględnego "naprawienia" tych naruszeń zmieniających znaczenie), ale uważaj, jeśli używasz agresywnego, być może będziesz musiał debugować ... (np. W numpy / pandas, True == np.bool_(True)ale nieTrue is np.bool_(True) !)

Możesz sprawdzić, ile naruszeń każdego rodzaju (przed i po):

pep8 --quiet --statistics .

Uwaga: uważam, że E501s (zbyt długa linia) to szczególny przypadek, ponieważ prawdopodobnie będzie ich dużo w twoim kodzie, a czasami nie są one korygowane przez autopep8.

Jako przykład zastosowałem tę technikę do kodu bazowego pand .

Andy Hayden
źródło
@hayden Czy masz jakieś uwagi na temat tego, na ile jest to niezawodne i jaki jest stosunek poprawek automagicznych do dziwnych problemów, które wprowadza?
Marius,
@Marius Użyłem tego na kodzie pand (który jest dość duży) i nie pokazywał żadnych dziwnych problemów, nie zmieni kodu, który zmieni znaczenie , zaktualizowałem moją odpowiedź, aby o nich wspomnieć. Wcześniej występował problem z hashbangiem Sphinxa (błąd w PEP8 został już naprawiony).
Andy Hayden
2
Czy to wymusza Strunk i White w komentarzach?
Eric
1
Od 25 października 2017 r. pep8Nazwa pakietu wymienionego w tej odpowiedzi została zmieniona na pycodestyle: github.com/PyCQA/pycodestyle/releases/tag/1.7.1
hb20007
8

@Andy Hayden dał dobry przegląd autopep8. Oprócz tego istnieje jeszcze jeden pakiet o nazwie pep8ify, który również robi to samo.

Jednak oba pakiety mogą usuwać tylko błędy lint, ale nie mogą formatować kodu.

little = more[3:   5]

Powyższy kod pozostaje taki sam również po pep8ify. Ale kod jeszcze nie wygląda dobrze. Możesz użyć elementów formatujących, takich jak yapf , które sformatują kod, nawet jeśli jest zgodny z PEP8. Powyższy kod zostanie sformatowany na

little = more[3:5]

Czasami nawet niszczy to ręczne formatowanie. Na przykład

BAZ = {
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]
}

zostanie przekonwertowany na

BAZ = {[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]}

Ale możesz powiedzieć mu, aby zignorował niektóre części.

BAZ = {
   [1, 2, 3, 4],
   [5, 6, 7, 8],
   [9, 10, 11, 12]
}  # yapf: disable

Zaczerpnięte z mojego starego posta na blogu: Automatycznie PEP8 i formatuj swój kod Pythona!

ChillarAnand
źródło
2
Czy little = more[3: 5]jest błąd w pep8 (biblioteka)? yapf to zdecydowanie przyszłość, algorytm za nim (zasadniczo najkrótsza ścieżka na wykresie wszystkich opcji formatowania) jest bardzo eleganckim rozwiązaniem i prawdopodobnie będzie miał mniej błędów, a także formatowanie kanoniczne.
Andy Hayden
@AndyHayden Wygląda na to, że to brakująca funkcja, nie naprawia E225
ChillarAnand
5

Jeśli używasz eclipse + PyDev, możesz po prostu aktywować autopep8 w ustawieniach PyDev: Windows -> Preferencje -> wpisz „autopep8” w filtrze wyszukiwania.

Sprawdź „Użyj autopep8.py do formatowania kodu?” -> OK

Teraz formatowanie kodu CTRL-SHIFT-F eclipse powinno sformatować twój kod za pomocą autopep8 :)

zrzut ekranu

mork
źródło
3

Przeprowadziłem szerokie badania na temat różnych instrumentów dla języka Python i stylu kodu. Istnieją dwa rodzaje instrumentów: linters - analizujący twój kod i ostrzegający o źle użytych stylach kodu i pokazujący porady, jak to naprawić, oraz elementy formatujące kod - po zapisaniu pliku ponownie formatuje dokument przy użyciu stylu PEP.

Ponieważ ponowne formatowanie musi być dokładniejsze - jeśli przerabia coś, czego nie chcesz, stało się bezużyteczne - obejmuje mniejszą część PEP, linters pokazuje znacznie więcej.

Wszystkie mają różne uprawnienia do konfiguracji - na przykład pylinter konfigurowalny we wszystkich jego regułach (można włączyć / wyłączyć każdy typ ostrzeżeń), czarny w ogóle nieskonfigurowalny.

Oto kilka przydatnych linków i samouczków:

Dokumentacja:

Linters (według popularności):

Elementy formatujące kod (według popularności):

Mikhail_Sam
źródło
1

Jest wiele.

IDE zwykle mają wbudowane pewne możliwości formatowania. IntelliJ Idea / PyCharm ma, to samo dotyczy wtyczki Pythona dla Eclipse i tak dalej.

Istnieją elementy formatujące / lintery, które mogą kierować reklamy na wiele języków. https://coala.io jest tego dobrym przykładem.

Następnie są narzędzia przeznaczone do jednego celu, z których wiele jest wymienionych w innych odpowiedziach.

Jedną z metod automatycznego ponownego formatowania jest przeanalizowanie pliku do drzewa AST (bez usuwania komentarzy), a następnie zrzucenie go z powrotem do tekstu (co oznacza, że ​​nic z oryginalnego formatowania nie jest zachowywane). Przykładem może być https://github.com/python/black .

user7610
źródło