Czasami łamię długie warunki if
ws na kilku liniach. Najbardziej oczywistym sposobem na to jest:
if (cond1 == 'val1' and cond2 == 'val2' and
cond3 == 'val3' and cond4 == 'val4'):
do_something
Nie jest bardzo atrakcyjny wizualnie, ponieważ akcja miesza się z warunkami. Jest to jednak naturalny sposób przy użyciu prawidłowego wcięcia w Pythonie 4 spacji.
W tej chwili używam:
if ( cond1 == 'val1' and cond2 == 'val2' and
cond3 == 'val3' and cond4 == 'val4'):
do_something
Ale to nie jest bardzo ładne. :-)
Czy możesz polecić alternatywny sposób?
python
coding-style
if-statement
Eli Bendersky
źródło
źródło
pep8
kryteria pakietu. Wpep8
pakiet za problem # 126 jest o ustalenie pakiet ściśle przestrzegać spec PEP8. Dyskusja na ten temat zawiera również sugestie dotyczące stylu, które można zobaczyć tutaj.Odpowiedzi:
Nie musisz używać 4 spacji w drugiej linii warunkowej. Może użyć:
Nie zapominaj też, że biała spacja jest bardziej elastyczna niż myślisz:
Oba są jednak dość brzydkie.
Może stracisz nawiasy kwadratowe (jednak Przewodnik po stylu odradza to)?
To przynajmniej daje pewne rozróżnienie.
Lub nawet:
Myślę, że wolę:
Oto przewodnik po stylach , który (od 2010 r.) Zaleca stosowanie nawiasów.
źródło
and
iif
.W zdegenerowanym przypadku uciekłem się do następujących przypadków, w których są to po prostu AND lub OR.
Goli kilka znaków i wyjaśnia, że warunek nie jest subtelny.
źródło
if destroy_world and DestroyTheWorld() == world_is_destroyed: ...
. Świetnie, teraz właśnie przypadkiem zniszczyłeś świat. JAK MOGŁEŚ?Ktoś musi tutaj poprzeć pionowe białe znaki! :)
Dzięki temu każdy warunek jest wyraźnie widoczny. Pozwala także na czystsze wyrażanie bardziej złożonych warunków:
Tak, dla przejrzystości wymieniamy trochę pionowych nieruchomości. Warto IMO.
źródło
and
jak równieżor
) jest po operatora, a nie przed nim.PEP8
ale utrudnia określenie operacji logicznej, którą łączysz. Zrobiłbym to, gdyby przyszedł do mojego biurka poprzez przegląd kodu.Wolę ten styl, gdy mam strasznie duży warunek if:
źródło
and
ior
operatorów na początku linii narusza PEP 0008 , który stwierdza: „Preferowanym miejscem na obejście operatora binarnego jest po nim, a nie przed nim”. . Lubię jednak klamrę zamykającą i dwukropek na ich własnej linii, aby oddzielić warunek if od ciała (i jest to całkowicie możliwe, zachowując operatorów boolowskich na końcu linii dla zgodności z PEP-0008).For decades the recommended style was to break after binary operators. But this can hurt readability in two ways
...In Python code, it is permissible to break before or after a binary operator, as long as the convention is consistent locally. For new code Knuth's style is suggested.
(stylem Knutha jest rozpoczęcie linii od operatora).Oto moje bardzo osobiste podejście: długie warunki są (moim zdaniem) zapachem kodu, który sugeruje refaktoryzację do funkcji / metody zwracającej wartość logiczną. Na przykład:
Teraz, gdybym znalazł sposób na poprawienie warunków na wielu liniach, prawdopodobnie zadowoliłbym się ich posiadaniem i pominąłbym refaktoryzację.
Z drugiej strony, ich zakłócenie mój zmysł estetyczny stanowi zachętę do refaktoryzacji.
W związku z tym doszedłem do wniosku, że warunki na wielu liniach powinny wyglądać brzydko i jest to zachęta do ich unikania.
źródło
To nie poprawia się tak bardzo, ale ...
źródło
Sugeruję przeniesienie
and
słowa kluczowego do drugiej linii i wcięcie wszystkich linii zawierających warunki dwoma spacjami zamiast czterech:Właśnie tak rozwiązuję ten problem w moim kodzie. Posiadanie słowa kluczowego jako pierwszego słowa w wierszu sprawia, że warunek jest znacznie bardziej czytelny, a zmniejszenie liczby spacji dodatkowo odróżnia warunek od działania.
źródło
Wydaje się, że warto zacytować PEP 0008 (oficjalny przewodnik po stylu Pythona), ponieważ skromnie komentuje to zagadnienie:
Zwróć uwagę na „nieograniczony do” w powyższym cytacie; oprócz podejść sugerowanych w przewodniku po stylu, niektóre z sugerowanych w innych odpowiedziach na to pytanie są również dopuszczalne.
źródło
Oto, co robię, pamiętaj, że „wszystko” i „każdy” akceptuje iterowalność, więc po prostu umieszczam długi warunek na liście i pozwalam „wszystkim” wykonać pracę.
źródło
Jestem zaskoczony, że nie widzę mojego preferowanego rozwiązania,
Ponieważ
and
jest to słowo kluczowe, zostaje ono wyróżnione przez mój edytor i wygląda wystarczająco inaczej niż do_something poniżej.źródło
Dodając do tego, co powiedział @krawyoti ... Długie warunki pachną, ponieważ są trudne do odczytania i trudne do zrozumienia. Użycie funkcji lub zmiennej sprawia, że kod jest wyraźniejszy. W Pythonie wolę używać spacji pionowej, otaczać nawiasy i umieszczać operatory logiczne na początku każdej linii, aby wyrażenia nie wyglądały jak „swobodne”.
Jeśli warunki wymagają oceny więcej niż raz, jak w
while
pętli, najlepiej jest użyć funkcji lokalnej.źródło
Osobiście lubię dodawać znaczenie do długich instrukcji if. Musiałbym przeszukać kod, aby znaleźć odpowiedni przykład, ale oto pierwszy przykład, który przychodzi mi na myśl: powiedzmy, że wpadłem na dziwaczną logikę, w której chcę wyświetlić określoną stronę w zależności od wielu zmiennych.
Angielski: „Jeśli zalogowany użytkownik NIE jest nauczycielem-administratorem, ale jest zwykłym nauczycielem i sam nie jest uczniem…”
Pewnie może to wyglądać dobrze, ale czytanie ich, jeśli stwierdzenia to dużo pracy. A może przypiszemy logikę do etykiety, która ma sens. „Etykieta” jest w rzeczywistości nazwą zmiennej:
Może się to wydawać głupie, ale możesz mieć jeszcze jeden warunek, w którym TYLKO chcesz wyświetlić inny element tylko wtedy i tylko wtedy, gdy wyświetlasz panel nauczyciela LUB jeśli użytkownik ma domyślnie dostęp do tego innego określonego panelu:
Spróbuj napisać powyższy warunek bez użycia zmiennych do przechowywania i etykietowania swojej logiki, i nie tylko otrzymujesz bardzo niechlujne, trudne do odczytania zdanie logiczne, ale po prostu powtórzyłeś się. Chociaż istnieją uzasadnione wyjątki, pamiętaj: Don't Repeat Yourself (DRY).
źródło
„all” i „any” są dobre dla wielu warunków tego samego typu. ALE zawsze oceniają wszystkie warunki. Jak pokazano w tym przykładzie:
źródło
all()
, chyba że zamierzasz zawinąć je w lambda i użyć swojejf()
sztuczki, wszystkie zostaną ocenione. Innymi słowy, Aaron: Myślę, że Anders starał się mówić ogólnie o warunkach, wykorzystując kallaby jako konkretny przykład; ale duplika dotyczy tylko funkcji.(Lekko zmodyfikowałem identyfikatory, ponieważ nazwy o stałej szerokości nie są reprezentatywne dla prawdziwego kodu - przynajmniej nie prawdziwego kodu, z którym się spotykam - i uwierzę w czytelność przykładu).
Działa to dobrze w przypadku „i” i „lub” (ważne, aby były pierwsze w drugiej linii), ale znacznie mniej w przypadku innych długich warunków. Na szczęście te pierwsze wydają się być bardziej powszechnym przypadkiem, podczas gdy te drugie często można łatwo przepisać za pomocą zmiennej tymczasowej. (Zazwyczaj nie jest to trudne, ale może być trudne lub znacznie mniej oczywiste / czytelne, aby zachować zwarcie „i” / „lub” podczas przepisywania.)
Ponieważ znalazłem to pytanie w Twoim blogu na temat C ++ , dodam , że mój styl C ++ jest identyczny:
źródło
Prosty i prosty, również przechodzi testy pep8:
W ostatnim czasie wolałem funkcje
all
iany
, ponieważ rzadko mieszam porównania And i Or, działa to dobrze i ma dodatkową zaletę: wczesne niepowodzenie ze zrozumieniem generatorów:Pamiętaj tylko, aby przekazać jedną iterację! Przekazywanie N-argumentów jest nieprawidłowe.
Uwaga:
any
jest jak wieleor
porównań,all
jest jak wieleand
porównań.To ładnie łączy się ze zrozumieniem generatora, na przykład:
Więcej na: zrozumienie generatora
źródło
Co jeśli wstawimy tylko dodatkową pustą linię między stanem a ciałem, a resztę wykonamy w sposób kanoniczny?
ps Zawsze używam tabulatorów, a nie spacji; Nie mogę dostroić ...
źródło
and
ior
powinny zaczynać się w następnym wierszuZwykle robię to:
w ten sposób klamra zamykająca i dwukropek wizualnie oznaczają koniec naszego stanu.
źródło
and
lubor
.Wszyscy respondenci, którzy udostępniają również wiele warunków warunkowych dla instrukcji if, są tak samo brzydkie, jak przedstawiony problem. Nie rozwiązujesz tego problemu, robiąc to samo…
Nawet odpowiedź PEP 0008 jest odpychająca.
Oto znacznie bardziej czytelne podejście
Chcesz, żebym zjadł moje słowa? Przekonaj mnie, że potrzebujesz wielu warunków, a ja dosłownie wydrukuję to i zjem to dla twojej rozrywki.
źródło
Myślę, że rozwiązanie @ zkanda byłoby dobre z niewielkim zwrotem akcji. Jeśli posiadasz swoje warunki i wartości na ich własnych listach, możesz użyć porównania list, aby dokonać porównania, co uczyniłoby sprawę nieco bardziej ogólną dla dodawania par warunek / wartość.
Gdybym chciał zakodować takie zdanie w taki sposób, napisałbym to w taki sposób, aby zapewnić czytelność:
I po prostu rzucić inne rozwiązanie z
iand
operatorem :źródło
all(map(eq, have, expected))
. (zfrom operator import eq
)Kilka innych przypadkowych pomysłów dla kompletności. Jeśli działają dla Ciebie, użyj ich. W przeciwnym razie prawdopodobnie lepiej będzie spróbować czegoś innego.
Możesz to również zrobić za pomocą słownika:
Ta opcja jest bardziej skomplikowana, ale może się również przydać:
Nie wiem, czy to działa dla Ciebie, ale jest to kolejna opcja do rozważenia. Oto jeszcze jeden sposób:
Dwa ostatnie, których nie testowałem, ale koncepcje powinny wystarczyć, aby zacząć, jeśli z tym chcesz.
(A dla przypomnienia, jeśli jest to jednorazowa sprawa, prawdopodobnie lepiej będzie skorzystać z metody przedstawionej na początku. Jeśli porównujesz w wielu miejscach, metody te mogą zwiększyć czytelność na tyle, aby nie czujesz się tak źle z powodu faktu, że są trochę hacky).
źródło
Walczyłem też o znalezienie przyzwoitego sposobu, aby to zrobić, więc właśnie wpadłem na pomysł (nie srebrną kulę, ponieważ jest to głównie kwestia gustu).
Znalazłem kilka zalet tego rozwiązania w porównaniu do innych, które widziałem, a mianowicie otrzymujesz dokładnie 4 dodatkowe wcięcia (bool), pozwalając na wyrównanie wszystkich warunków w pionie, a treść instrukcji if można wciąć w jasny (ish) sposób. Zachowuje to również zalety oceny zwarcia operatorów logicznych, ale oczywiście dodaje narzut wywołania funkcji, która w zasadzie nic nie robi. Można argumentować (słusznie), że każda funkcja zwracająca swój argument może być tutaj użyta zamiast bool, ale jak powiedziałem, to tylko pomysł i ostatecznie kwestia gustu.
Zabawne, kiedy to pisałem i myślałem o „problemie”, wpadłem na jeszcze jeden pomysł, który usuwa narzut wywołania funkcji. Dlaczego nie wskazać, że za chwilę wejdziemy w złożony stan, używając dodatkowych par nawiasów? Powiedz jeszcze 2, aby uzyskać ładne wcięcie o 2 spacje warunków podrzędnych względem treści instrukcji if. Przykład:
Podoba mi się to, ponieważ kiedy na to patrzysz, natychmiast dzwoni ci w głowie dzwonek: „hej, dzieje się tu coś skomplikowanego! . Tak, wiem, że nawiasy nie poprawiają czytelności, ale warunki te powinny pojawiać się rzadko, a kiedy się pojawią, i tak będziesz musiał je zatrzymać i uważnie przeczytać (ponieważ są złożone ).
Tak czy inaczej, jeszcze dwie propozycje, których tu nie widziałem. Mam nadzieję, że to komuś pomoże :)
źródło
Możesz podzielić go na dwie linie
Lub nawet dodaj jeden warunek na raz. W ten sposób przynajmniej oddziela bałagan od
if
.źródło
Wiem, że ten wątek jest stary, ale mam trochę kodu Python 2.7 i PyCharm (4.5) wciąż narzeka na ten przypadek:
Nawet jeśli ostrzeżenie PEP8 „wizualnie wcięty wiersz z takim samym wcięciem jak następny wiersz logiczny”, rzeczywisty kod jest całkowicie OK? To nie jest „nadmierne wcięcie?”
... są chwile, w których chciałbym, żeby Python ugryzł kulę i po prostu poszedł z kręconymi klamrami. Zastanawiam się, ile błędów wprowadzono przypadkowo na przestrzeni lat z powodu przypadkowego błędnego wcięcia ...
źródło
Spakuj swoje warunki do listy, a potem zrób coś. lubić:
źródło
Uważam, że gdy mam długie warunki, często mam krótki kod. W takim przypadku po prostu podwójnie wcięłem ciało, a zatem:
źródło
lub jeśli jest to jaśniejsze:
W tym przypadku nie ma powodu, dla którego wcięcie powinno być wielokrotnością liczby 4, np. Patrz „Wyrównany z ogranicznikiem otwarcia”:
http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Indentation#Indentation
źródło
Oto inne podejście:
Ułatwia to także łatwe dodanie kolejnego warunku bez zmiany instrukcji if, po prostu dodając inny warunek do listy:
źródło
Zwykle używam:
źródło
jeśli nasz warunek if & else musi wykonać w nim wiele instrukcji, możemy napisać jak poniżej. Za każdym razem, gdy mamy przykład z jednym stwierdzeniem w środku.
Dzięki, to działa dla mnie.
źródło
Przepraszam, moja noobness, ale zdarza się, że nie jestem tak dobrze zaznajomiony z #Python, jak ktokolwiek z was tutaj, ale zdarza się, że znalazłem coś podobnego podczas pisania własnych obiektów w modelowaniu 3D BIM, więc dostosuję mój algorytm do python.
Problem, który tu znajduję, jest dwustronny:
Aby ominąć wszystkie te problemy, skrypt musi działać w ten sposób
Zalety tej metody:
Skrypt jest czytelny.
Skrypt można łatwo utrzymać.
Mam nadzieję, że pomoże wam wszystkim
źródło