2012-12-31 20 views
6

In Python 2.7.1, sto provando a fornire un elenco di messaggi come primo argomento e un elenco di colori come secondo argomento. Voglio il secondo argomento di default su un elenco di bianchi se non è fornito. Questo è il modo in cui ho provato a farlo:Comprensione delle liste negli argomenti delle funzioni

def multicolor_message(msgs, colors=[libtcod.white for x in len(msgs)]): 
#function body 

libtcod.white è una parte della libreria che sto usando e non è in alcun modo causare alcun problema. Il compilatore dice che la variabile msgs non è definita. Ovviamente la variabile msgs non esiste in questo ambito, ma ho bisogno di creare un elenco di lunghezza appropriata e assegnarlo a colors. Qual è il modo più pulito per farlo?

+0

è necessario fornire il messaggio di stacktrace/errore –

+1

inizializzare i valori non definiti nel corpo della funzione, o chiamala tramite una funzione wrapper che fa questo per te. – tripleee

+0

@InbarRose In questo caso lo stacktrace non era necessario per vedere cosa c'è che non va – piokuc

risposta

6

farei così:

def multicolor_message(msgs, colors=None): 
    if colors is None: 
    colors=[libtcod.white for x in len(msgs)] 
+4

E il motivo per farlo in questo modo è che non è possibile fare riferimento ad altri argomenti della stessa funzione nei valori predefiniti. I valori predefiniti vengono valutati nell'ambito di definizione della funzione e gli argomenti stessi esistono solo dopo aver chiamato la funzione. –

+0

@MattiVirkkunen Proprio così. – piokuc

+2

Un altro motivo importante è che [argomenti mutabili predefiniti] (http://stackoverflow.com/q/1132941/395760) raramente fanno ciò che vuoi. – delnan

4

Questo non è possibile è pitone, come argomenti di default della funzione vengono eseguiti in fase di definizione di funzione e la variabile msgs non saranno disponibili fino a quando viene chiamata la funzione.

Dal docs: i valori dei parametri

predefiniti vengono valutati quando la definizione di funzione è eseguita. Ciò significa che l'espressione viene valutata una volta, quando viene definita la funzione e viene utilizzato lo stesso valore "pre-calcolato" per ciascuna chiamata. Questo è particolarmente importante quando un parametro predefinito è un oggetto mutabile, come un elenco o un dizionario: se la funzione modifica l'oggetto (ad esempio aggiungendo un elemento a un elenco ), il valore predefinito è in effetti modificato . Questo generalmente non è ciò che era inteso. Un modo per aggirare questo è quello di utilizzare None come predefinito, e testare esplicitamente per esso nel corpo della funzione, ad esempio:

def whats_on_the_telly(penguin=None): 
    if penguin is None: 
     penguin = [] 
    penguin.append("property of the zoo") 
    return penguin 
+0

Non in fase di compilazione. Al momento della definizione della funzione. La differenza è importante per le funzioni nidificate o quando vengono utilizzati nomi a livello di modulo nelle espressioni. – delnan