Esempi concreti del "solo un modo per farlo" di Python maxim [closed]

34

Sto imparando Python e sono intrigato dal seguente punto in PEP 20 The Zen of Python :

There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch.

Qualcuno potrebbe offrire esempi concreti di questa massima? Sono particolarmente interessato al contrasto con altre lingue come Ruby. Parte della filosofia del design di Ruby (originata da Perl, credo?) È che i molteplici modi di farlo sono A Good Thing. Qualcuno può offrire alcuni esempi che mostrano i pro e i contro di ciascun approccio. Nota, non ho una risposta alla quale è meglio (che è probabilmente troppo soggettiva per essere mai risolta), ma piuttosto un confronto imparziale dei due stili.

    
posta Charles Roper 27.07.2011 - 18:43
fonte

4 risposte

47

Rispetto a linguaggi come Perl, Python ha un numero limitato di costrutti di controllo:

  • solo if e nessun unless ,
  • solo for che scorre su sequenze e senza foreach o C-style for ,
  • solo while che controlla una condizione ogni ciclo e nessuna do-while ,
  • solo if-elif e nessun switch ,
  • c'è solo un costrutto di commento, # , e per ogni riga puoi dire se è commentato o meno, senza guardare le righe precedenti.

Inoltre, c'è quasi un modo per indentare la tua fonte; la maggior parte dei casi di indentazione creativa sono sintatticamente esclusi.

Questo rende l'analisi di una fonte Python più facile per gli esseri umani.

Ci sono tentativi di essere minimi ma completi nei tipi built-in e nella libreria standard.

  • per la lista mutabile si usa l'unico tipo built-in list ; è O (1) per la maggior parte delle operazioni e non devi mai scegliere l'implementazione corretta,
  • per gli elenchi immutabili, allo stesso modo, devi solo usare il tipo tuple ,
  • per le mappe, si utilizza l'unico dict incorporato che è dannatamente efficiente nella maggior parte dei casi, non occorre riflettere su quale implementazione utilizzare.

Python 3 estende questo valore ai numeri interi: non importa quanto sia grande il numero intero, si usa lo stesso tipo e non si preoccupa mai della coercizione.

Python cerca di evitare lo zucchero sintattico. Ma a volte aggiunge zucchero sintattico solo per rendere ovvio il modo ovvio. Puoi scrivere if foo is not None invece di if not (foo is None) perché 'is not' è di tipo speciale. Ancora foo is not None legge facilmente, non può essere interpretato male, e non devi pensare, scrivi semplicemente la cosa ovvia.

Naturalmente, la maggior parte delle cose più complesse in in Python possono essere eseguite in diversi modi. Puoi aggiungere metodi alle classi per dichiarazione o per assegnazione di slot semplice, puoi passare argomenti a funzioni in un certo numero di modi creativi, ecc. Questo perché gli interni della lingua sono per lo più esposti.

La chiave è che c'è sempre un modo che è destinato a essere il migliore, il caso di copertura. Se esistono altri modi, non sono stati aggiunti come alternative uguali (come if e unless ) ma si limitano a esporre i meccanismi interni. Lentamente ma costantemente tali alternative sono obsolete (non eliminate!) Migliorando il meccanismo migliore noto.

I decoratori eseguono il wrap delle chiamate AOP. Prima di 2.6 dovevi usare __metaclass__ magic member per dichiarare il metaclasse di una classe; ora puoi usare la stessa sintassi del decoratore anche per questo. Precedentemente alla versione 3.0 avevi due tipi di stringhe, orientate ai byte e Unicode, che potresti inavvertitamente mescolare. Ora hai l'unico% Unicode% co_de e l'unico str trasparente binario, che non puoi mescolare per errore.

    
risposta data 27.07.2011 - 20:13
fonte
10

Un altro paio di esempi sono:
len() è una funzione invece di un metodo presente in ogni sequenza; se confronti con Java hai .length , .size() , .getSize() e altri metodi per trovare il numero di elementi in una sequenza.

Un altro esempio è il fatto che .join() è un metodo string , non un metodo presente in ogni sequenza. Non hai bisogno di sapere se il parametro join è una lista, un set, una comprensione, o qualsiasi altra cosa, funzionerà.

    
risposta data 07.08.2011 - 20:12
fonte
8

In C ci sono molti modi possibili per aumentare il valore di una variabile di uno:

i++     // Post-increment, returns the number before the increment
++i     // Pre-increment, returns the number after the increment
i += 1 

Ognuno finisce per aumentare il valore di i di 1 , ma ognuno è leggermente diverso.

In Python, c'è davvero solo un modo; aggiungine uno.

i += 1

E anche se c'è più di un modo sintatticamente valido per farlo (ad esempio i = i + 1 ), stai facendo la stessa cosa con gli stessi effetti collaterali.

    
risposta data 27.07.2011 - 20:10
fonte
6

Un'altra possibilità potrebbe essere la comprensione delle liste. In Python, potresti fare questo:

new_list = []
    for item in list_of_items:
       if item < 10:
           new_list.append(item)

Ma il modo "ovvio" (se sei olandese o hai più familiarità con Python) di farlo sarebbe con una comprensione di lista:

new_list = [item for item in list_of_items if item < 10]

È più breve, la new_list viene creata in un solo passaggio, corre più veloce, credo, ed è elegante. Sul lato negativo, si potrebbe sostenere che sembra meno esplicito, ma penso che una volta che ci si abitui, è altrettanto esplicito.

    
risposta data 01.08.2011 - 19:08
fonte

Leggi altre domande sui tag