Deoarece nu este necesar să se scrie în Python, partea 1 - un jurnal de bord

Deși unul dintre postulatele modul Python este expresia „Ar trebui să fie una - și, de preferință, un singur - un mod evident de a face acest lucru“ - în realitate, nu este așa. În limba de o mulțime de moduri de a face ceva mod evident pentru un începător, dar în căutarea unui Pythonistas teribil cu experiență (și vice-versa). Cel mai rau lucru pe care, în ciuda tuturor eforturilor depuse de Guido și compania, acest proces poate fi chiar mai mult de unul.

În Python, la fel ca în orice limbă, puteți scrie sau idiomatică sau rău. Desigur, chiar și în scris, în deplină concordanță cu cele mai bune practici pot realiza un algoritm complicat, care nu este foarte bun. Dar, în afară de trist, ceea ce ar putea fi mai bine decât un algoritm bun pus în aplicare în mod corect și idiomatic?

Acum, despre cum să scrie și cum să nu.

Pitonul toate structurile de date standard sunt iteratori și nu necesită indici de indicații explicite. Dar, mai întâi, vechile obiceiuri de multe ori prevalează și îndemne să scrie ceva de genul:

De fapt, indicele de aici - este o entitate în plus, care este lipsită de sens. Scrie corect:

Dar pentru a obține indexul în secvența poate fi mult mai elegant (dacă aveți nevoie de ea):

Dar acest lucru se întâmplă aveți nevoie de un pic mai des decât oricând.

Pe scurt: dacă poți face fără indici - trebuie să faci fără ele.

Cicluri la locul și nu foarte

Am venit din alte limbi (C, C ++, Perl, Java) este un obicei de a utiliza cicluri ori de câte ori este necesar ocolind colectarea, deși în Python ei în cele mai multe cazuri, pot fi înlocuite cu alte instrumente: expresii generatoare sau funcții de ordin superior.

Sarcina Trivial: trebuie să alegeți dintr-o listă de utilizatori care au is_paid set de proprietăți la True. Bad decizie:

Cum se scrie corect:

Acum nu avem nivelul suplimentar de cuibărit și codul este citit ca o singură propoziție, mai degrabă decât ca o secvență de acțiuni. În plus, nu vă puteți întoarce lista, și generatorul (leneș pentru a face calculul), schimbând doar paranteza pătrat în runda:

Dacă toate acestea se pare ciudat și de neînțeles - este timpul să se întoarcă la lectură Lutz :)

Acum, pentru funcțiile de ordin superior. Să presupunem că avem o sarcină simplă: există o variabilă de înregistrări, reprezentând un iterator pentru obiecte de o proprietate de valoare. Este necesar să se calculeze suma valorilor în acest domeniu în toate obiectele.

Cât de des scrie:

Trei linii care nu miros și declarative. Dar, așa cum a fost necesar să-l scrie:

Dacă avem de a efectua pe o listă de alte funcții - ușor folosite reduce. Cu atenție, deoarece reduce, în unele cazuri, nu funcționează la fel de repede cum ne-ar dori (acest lucru va fi mai mic).

Și, puteți utiliza funcția de hartă și filtru ca o expresie generatoare alternative. Dar aceasta este un amator.

Pe scurt: nu utilizați bucle, în cazul în care le puteți utiliza instrumentele de nivel superior, cum ar fi funcții pentru lucrul cu liste, funcții de ordin superior (hartă, filtru, reduce) sau generatoare de expresie.

Biciclete în loc de mijloacele standard de limbă

Un exemplu este o operație foarte banal de concatenare șir.

Atunci când o persoană este impregnată cu paradigma functionala, mâinile sale ajungând la împinge unele tehnici ori de câte ori lucrurile lor nu este în valoare de mai mult decât o anumită limbă. De exemplu, în același concatenarea șir.

Dacă te uiți la ce se întâmplă: la fiecare pas, o nouă linie care să unească toate cele anterioare și completează-l cu un nou fragment de moduri - ca o consecință, memoria scurgeri de tone.

Apropo, unii dintre cei a căror creier este destul de gol în legătură cu orice funktsionalschine a scrie mai bine (un exemplu de cod real):

La fel reduce, realizat doar mâinile, cu toate neajunsurile sale, excesul de path_part substanță și un nivel suplimentar de imbricare. Iată o modalitate mai bună:

Acesta funcționează rapid și necesită doar memorie liniară pentru a lucra.

Python are o mulțime de built-in caracteristici care fac viața mai ușoară. De exemplu, nu sunt familiarizați cu funcțiile încorporate pot fi pe cale de a scrie un astfel de cod minunat:

Deși ai putea scrie decizie banală și mai repede (chiar este mai rapid, datorită faptului că suma efectiv - sishny de legare):

Să ne întoarcem la exemplul anterior despre inserarea calea fișierului. în acest exemplu, codul este legat de UNIX platforma pentru utilizarea slash „/“. În codul reală, desigur, corect de a utiliza funcția de built-in-platformă independentă a modulului os:

Pe scurt: nu este necesar să se reinventeze din nou, bicicletele lor în cazul în care, în limba are deja o soluție la cheie. Și deciziile abundă:

  • Funcții min și max.
  • Setați (cele mai simple elemente mod prounikalit în lista nesortat, printre altele).
  • oricare și toate funcțiile.
  • Tipuri de date interesante în modulul colecții. O atenție deosebită trebuie acordată defaultdict și namedtuple.
  • Fiecare tip de date standard, există mai multe tehnici care pot facilita foarte mult viata.
  • Toate biblioteca standard.

Pe scurt: dacă puteți utiliza mijloace limbaj standard - trebuie să le folosească.

expresii ciudate în dacă este

Oamenii care au venit de la alte PL, uneori, scrie ceva de genul:

Cineva care a citit despre operatorul este poate scrie astfel:

Sau chiar mai interesant pentru structuri de date:

Cineva s-ar putea aminti că expresia în cazul în care nu trebuie să compare în mod explicit cu Adevărat sau fals, dar nu uitați că valoarea expresiei este implicit Cast la tipul bool:

Exemplele de mai sus trebuie să fie rescrisă ca:

Reguli pentru a aduce bool simplu și descrise în documentația standard de. Pe scurt, o minciună, atunci când pentru a reveni-turnare tip:

  • nici unul
  • fals
  • Numărul 0 în toate formele sale (0, 0,0, 0J).
  • Structura de date standard Blank (<>, (), '', []).
  • Copii clase de utilizatori, care definesc bool metode () sau Len (), iar în cazul în care aceste metode return 0 sau fals.

Pe scurt: dacă aveți nevoie pentru a scrie instrucțiuni ca în cazul în <выражение>: Fără comparații cu mulaje Adevărat sau fals și explicite

Manipularea necorespunzătoare a excepțiilor

De fapt, o astfel de problemă am văzut nu numai în Python, dar acest lucru este în cazul în care ea a jucat uneori cu noi culori. Probleme, de fapt, două:

  1. Excepție de manipulare prin trecere.
  2. Procesarea îndeplinite toate într-un singur bloc, cu excepția eksepshenov.

Utilizarea pass

Problema nu este numai Python, dar alte limbi. Uneori, puteți vedea lucruri cum ar fi:

Cât de rău este? Excepție - situația este o situație de urgență, care trebuie să fie întotdeauna utilizate în mod explicit. Metoda de tratament depinde de caracteristicile codului: unele momente necesare din exploatarea forestieră, unele de ieșire pentru utilizator ca o eroare, în unele pur si simplu cad. Dar acesta este un subiect pentru un post separat.

Ceea ce este mai rău abordarea de mai sus? Există un risc pentru o lungă perioadă de timp să sape pentru a afla ce este în anexă a mers prost. Chiar mai mult - pentru a determina că ceva a mers prost doar de dovezi circumstanțiale, care raportează numai faptul de eroare (cel mai bun), dar nu spune nimic despre locul și motivul pentru care sa produs. Acest exemplu va da în mod constant în dicționarul gol ca valoarea parsed_json variabile, indiferent de ceea ce s-ar putea minți raw_json variabilă JSON (dacă ne imaginăm că undeva mai sus, este declarată).

Distracția începe, dacă nu specificați exact ceea ce trebuie să se ocupe de erori.

Manevrați toate excepțiile dintr-un bloc

Dacă introduceți codul de probă în interpret în secțiunea de mai sus - aceasta va funcționa fără erori. În timp ce în binele pe care nu ar trebui să nu importe JSON modul, și linia <много кода> - eroare de sintaxă generală. Acesta este același combo, ceea ce duce la multe ore petrecute pentru depanare necuvenit. Problemele ar fi putut fi evitate dacă numai excepțiile interceptate necesare:

Acum NameError și SyntaxError excepții vor fi prinse cu succes și ValueError și TypeError procesată cu succes. Aș dori să se constate că excepția SyntaxError este de obicei - CPython interpret verifică sintaxa este corectă numai în timpul rulării.

Sumar concluzie: este întotdeauna necesar să se precizeze în mod clar cum și ce excepțiile trebuie să fie prelucrate.