Python LanguageLa dichiarazione del passaggio

Sintassi

  • passaggio

Osservazioni

Perché vorresti mai dire all'interprete di fare esplicitamente nulla? Python ha il requisito sintattico che i blocchi di codice (dopo if , except , def , class ecc.) Non possono essere vuoti.

Ma a volte un blocco di codice vuoto è utile di per sé. Un blocco di class vuoto può definire una nuova classe diversa, ad esempio un'eccezione che può essere rilevata. Un blocco vuoto except può essere il modo più semplice per esprimere "chiedere perdono dopo" se non c'era nulla da chiedere perdono. Se un iteratore fa tutto il sollevamento pesante, può essere utile un loop vuoto for eseguire semplicemente l'iteratore.

Pertanto, se non si suppone che accada in un blocco di codice, è necessario un pass per tale blocco per non produrre un IndentationError . In alternativa, qualsiasi affermazione (incluso solo un termine da valutare, come il letterale Ellipsis ... o una stringa, più spesso una docstring) può essere usata, ma il pass chiarisce che effettivamente non dovrebbe accadere nulla, e non ha bisogno per essere effettivamente valutato e (almeno temporaneamente) memorizzato. Ecco una piccola raccolta annotata degli usi più frequenti del pass che incrociava la mia strada - insieme ad alcuni commenti sulla buona e cattiva pratica.

  • Ignorando (tutto o) un certo tipo di Exception (esempio da xml ):

     try:
         self.version = "Expat %d.%d.%d" % expat.version_info
     except AttributeError:
         pass # unknown
    

    Nota: ignorare tutti i tipi di rilanci, come nel seguente esempio dei pandas , è generalmente considerato una cattiva pratica, perché SystemExit anche eccezioni che dovrebbero probabilmente essere passate al chiamante, ad esempio KeyboardInterrupt o SystemExit (o anche HardwareIsOnFireError - How do you know non si sta eseguendo su una casella personalizzata con errori specifici definiti, che alcune applicazioni chiamanti vorrebbero conoscere?).

     try:
         os.unlink(filename_larry)
     except:
         pass
    

    Invece di usare almeno l' except Error: o in questo caso preferibilmente except OSError: è considerata una pratica molto migliore. Una rapida analisi di tutti i moduli python che ho installato mi ha dato che oltre il 10% di tutti except ...: pass istruzioni di except ...: pass catturano tutte le eccezioni, quindi è ancora un pattern frequente nella programmazione Python.

  • Derivazione di una classe di eccezioni che non aggiunge nuovi comportamenti (ad esempio in scipy ):

     class CompileError(Exception):
         pass
    

    Allo stesso modo, le classi intese come classe base astratta hanno spesso un __init__ vuoto esplicito o altri metodi che le sottoclassi dovrebbero derivare. (es. pebl )

     class _BaseSubmittingController(_BaseController):
         def submit(self, tasks): pass
         def retrieve(self, deferred_results): pass
    
  • Verificare che il codice funzioni correttamente per alcuni valori di test, senza preoccuparsi dei risultati (da mpmath ):

     for x, error in MDNewton(mp, f, (1,-2), verbose=0,
                              norm=lambda x: norm(x, inf)):
         pass
    
  • Nelle definizioni di classi o funzioni, spesso una docstring è già presente come istruzione obbligatoria da eseguire come unica cosa nel blocco. In questi casi, il blocco può contenere un pass in aggiunta alla docstring per poter dire "Questo è in effetti inteso a non fare nulla.", Ad esempio in pebl :

     class ParsingError(Exception): 
         """Error encountered while parsing an ill-formed datafile."""
         pass
    
  • In alcuni casi, pass è usato come segnaposto per dire "Questo metodo / classe / if-block / ... non è ancora stato implementato, ma questo sarà il posto giusto per farlo", anche se personalmente preferisco il letterale Ellipsis ... (NOTA: solo python-3) per distinguere strettamente tra questo e il "no-op" intenzionale nell'esempio precedente. Ad esempio, se scrivo un modello a grandi linee, potrei scrivere

     def update_agent(agent):
         ... 
    

    dove altri potrebbero avere

     def update_agent(agent):
         pass
    

    prima

     def time_step(agents):
         for agent in agents:
             update_agent(agent)
    

    come promemoria per update_agent funzione update_agent in un secondo momento, ma esegui alcuni test già per vedere se il resto del codice si comporta come previsto. (Una terza opzione per questo caso è il raise NotImplementedError . Ciò è utile in particolare per due casi: o "Questo metodo astratto dovrebbe essere implementato da ogni sottoclasse, non esiste un modo generico per definirlo in questa classe base" o "Questa funzione , con questo nome, non è ancora stato implementato in questa versione, ma questo è come sarà la sua firma " )

La dichiarazione del passaggio Esempi correlati