2012-12-31 5 views
6

Dans Python 2.7.1, j'essaie de fournir une liste de messages comme premier argument, et une liste de couleurs comme deuxième argument. Je veux que le deuxième argument par défaut à une liste de blancs si elle n'est pas fournie. Ceci est la façon dont j'ai essayé de le faire:Compréhension de la liste dans les arguments de la fonction

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

libtcod.white est une partie de la bibliothèque J'utilise et est en aucun cas causer de problèmes. Le compilateur dit que la variable msgs n'est pas définie. De toute évidence, la variable msgs n'existe pas dans cette étendue, mais je dois créer une liste de longueur appropriée et l'affecter à colors. Quelle est la façon la plus propre de le faire?

+0

vous devez fournir le message stacktrace/d'erreur –

+1

Initialiser valeurs non définies dans le corps de la fonction à la place, ou appelez-le via une fonction wrapper qui le fait pour vous. – tripleee

+0

@InbarRose Dans ce cas, stacktrace n'était pas nécessaire pour voir ce qui ne va pas – piokuc

Répondre

6

je le ferais comme ceci:

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

Et la raison pour cela est que vous ne pouvez pas référencer d'autres arguments de la même fonction dans les valeurs par défaut. Les valeurs par défaut sont évaluées dans la portée de définition de la fonction et les arguments eux-mêmes n'existent qu'une fois la fonction appelée. –

+0

@MattiVirkkunen C'est vrai. – piokuc

+2

Une autre raison importante est que [les arguments par défaut mutables] (http://stackoverflow.com/q/1132941/395760) font rarement ce que vous voulez. – delnan

4

Ce n'est pas possible est python, comme arguments par défaut de la fonction sont exécutées au moment de la définition de la fonction et votre variable msgs ne seront pas disponibles jusqu'à ce que la fonction est appelée.

De l'docs:

valeurs des paramètres par défaut sont évaluées lorsque la définition de la fonction est exécutée . Cela signifie que l'expression est évaluée une fois, lorsque la fonction est définie et que la même valeur "pré-calculée" est utilisée pour chaque appel. Ceci est particulièrement important pour comprendre quand un paramètre par défaut est un objet mutable, comme une liste ou un dictionnaire: si la fonction modifie l'objet (par exemple en ajoutant un élément à une liste ), la valeur par défaut est en effet modifiée . Ce n'est généralement pas ce qui était prévu. Une façon de contourner cela est d'utiliser Aucun comme valeur par défaut, et tester explicitement dans le corps de la fonction, par exemple:

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

Pas au moment de la compilation. Au moment de la définition de la fonction. La différence est importante pour les fonctions imbriquées ou lorsque des noms au niveau du module sont utilisés dans les expressions. – delnan

Questions connexes