2017-09-27 12 views
0

J'apprends Python.Comment utiliser les valeurs par défaut et les arguments arbitraires à un appel de fonction en Python?

J'ai appris à propos de la valeur par défaut et des arguments arbitraires. Donc, j'ai fait ma fonction qui a un paramètre offrant une valeur par défaut, et un autre paramètre ayant un nombre d'arguments arbitraire.

def make_pizza(size=15,*toppings): 
    """Summerize the pizza that we are about to make.""" 
    print("\nMaking a " + str(size) + 
    "-inch pizza with the following toppings: ") 
    for topping in toppings: 
     print("- " + topping) 


make_pizza('onion','shrimp','goda cheese','mushroom') 
make_pizza(17,'ham','extra meat','sweet con','pepperoni') 

Au premier appel de la fonction, je voulais utiliser la valeur par défaut du paramètre « taille » qui est « 15 » et « * garnitures » argument arbitraire.

Mais, je ne pouvais pas comprendre comment faire cela.

Quelqu'un peut-il me dire quand j'appelle une fonction avec plusieurs arguments, comment je peux utiliser les valeurs par défaut des paramètres et les arguments arbitraires à un appel de fonction?

Désolé à l'avance si vous vous sentez mal à l'aise avec mon anglais

Répondre

2

paramètres de mélange avec et sans valeurs par défaut peut en effet être déroutant. Les paramètres sont les noms utilisés dans la définition de la fonction, les arguments sont les valeurs transmises dans un appel.

Lorsque appelant, Python toujours remplir tous les paramètres d'arguments de position, y compris les noms avec des valeurs par défaut. size est juste un autre paramètre ici, même s'il a une valeur par défaut. Vous pouvez également utiliser la syntaxe name=value dans un appel pour affecter une valeur d'argument à un paramètre spécifique (qu'ils aient ou non une valeur par défaut).Mais vous ne pouvez pas dire à Python de ne pas attribuer quelque chose à size, pas à votre définition de fonction actuelle, car tout ce qui précède le paramètre *toppings est toujours va être un paramètre positionnel régulier.

Le paramètre *toppings ne capture que les arguments positionnels après tous les autres paramètres ont reçu des valeurs. Donc, 'onion' est affecté à size, et le reste est affecté à *toppings.

En Python 3, vous pouvez faire size un mot-clé seul paramètre, en les plaçant comme name=defaultaprès le nom *toppings, ou un * vide:

def make_pizza(*toppings, size=15): 

Maintenant size ne peut être réglé à partir d'un appel avec size=<new value> syntaxe d'argument mot-clé.

En Python 2, vous ne pouvez saisir de tels arguments de mots clés avec un fourre-tout paramètre **kwargs, après quoi vous devez regarder dans ce dictionnaire pour votre size:

def make_pizza(*toppings, **kwargs): 
    size = kwargs.get('size', 15) # set a default if missing 

Dans les deux cas, vous devez souvenez-vous de nommer explicitement size, et de mettre ces arguments clés explicitement nommés après les arguments de position:

make_pizza('ham', 'extra meat', 'sweet con', 'pepperoni', size=17) 
+0

Merci! Maintenant, je comprends quel était le problème. – Yeni

-1
def make_pizza(toppings,size=15): 
    """Summerize the pizza that we are about to make.""" 
    print("\nMaking a " + str(size) + 
    "-inch pizza with the following toppings: ") 
    for topping in toppings: 
     print("- " + topping) 


make_pizza(toppings = ['onion','shrimp','goda cheese','mushroom']) 
make_pizza(size = 17,toppings = ['onion','shrimp','goda cheese','mushroom']) 
0

Il y a un problème fondamental avec votre approche (je ne suis pas originaire.): Il est ambigu, car comment savez-vous si vous aviez l'intention comme size ou comme topping? Python ne peut pas faire cela, vous devez donc trouver une alternative.

Eh bien, vous pouvez simplement supprimer size de la liste d'arguments et d'interpréter le premier argument *toppings la taille si elle est un entier:

def make_pizza(*toppings): 
    if toppings and isinstance(toppings[0], int): 
     size, toppings = toppings[0], toppings[1:] 
    else: 
     size = 15 
    print("\nMaking a {}-inch pizza with the following toppings: ".format(size)) 
    for topping in toppings: 
     print("- " + topping) 

Quoi qu'il échouera dans les cas où une simple vérification de type n'est pas possible . Peut-être que la meilleure approche serait de faire toppings un argument normal et size un argument optionnel:

def make_pizza(toppings, size=15): 
    print("\nMaking a {}-inch pizza with the following toppings: ".format(size)) 
    for topping in toppings: 
     print("- " + topping) 

Cependant, vous devez passer dans une séquence pour toppings et il modifie l'ordre de toppings et size mais il est probablement beaucoup nettoyeur.

make_pizza(['onion','shrimp','goda cheese','mushroom']) 
make_pizza(['ham','extra meat','sweet con','pepperoni'], 17) 

Vous pouvez aussi garder les garnitures comme arbitraires arguments de position et de faire size un paramètre uniquement des mots clés par défaut (python3 uniquement):

def make_pizza(*toppings, size=15): 
    print("\nMaking a {}-inch pizza with the following toppings: ".format(size)) 
    for topping in toppings: 
     print("- " + topping) 

make_pizza('onion','shrimp','goda cheese','mushroom') 
make_pizza('ham','extra meat','sweet con','pepperoni', size=17) 
+0

Vous pouvez toujours garder '* toppings', il n'y a pas besoin de m prends-en un seul argument. –

+0

@MartijnPieters Juste, je pensais juste qu'il voulait 'size' comme argument positionnel. En utilisant '* toppings', vous obtiendrez un mot-clé' size = 15' à la fin (et python-3 seulement). – MSeifert