Précautions lors de l'attribution de valeurs par défaut aux arguments dans les définitions de fonctions Python

Python permet aux arguments d'avoir des valeurs par défaut lors de la définition d'une fonction.

La fonction ci-dessous récupère une valeur en spécifiant une clé pour le dictionnaire, mais renvoie la valeur par défaut de 0 si le dictionnaire ne contient pas la clé.

Python


def get(dic, key, default = 0):
    if key in dic:
        return dic[key]
    else:
        return default

Faisons le.

Python


#Préparez un dictionnaire
times_in_PPAP = {"pen": 2, "pineapple": 1, "apple": 1}

print "pen:\t",    get(times_in_PPAP, "pen")
print "apple:\t",  get(times_in_PPAP, "apple")
print "banana:\t", get(times_in_PPAP, "banana")

résultat


pen:	2
apple:	1
banana:	0

Puisque le stylo et la pomme sont inclus dans le dictionnaire, leurs valeurs sont renvoyées. Puisque la banane n'est pas incluse dans le dictionnaire, la valeur par défaut de 0 est renvoyée.

Il n'y a pas de problème pour l'instant. Considérons maintenant le cas suivant.

Python


dict_PPAP = {"PP": ["pen", "pineapple"], "AP": ["apple", "pen"],
             "PPAP": ["pen", "pineapple", "apple", "pen"]}

Ce dictionnaire est un dictionnaire qui stocke un tableau des prototypes correspondants pour l'acronyme. Écrivons une fonction similaire à celle ci-dessus pour ce dictionnaire.

Python


def restore_acronym(dic, key, default = []):
    if key in dic:
        return dic[key]
    else:
        return default

Je vais essayer.

Python


print "PP:", restore_acronym(dict_PPAP, "PP")
print "AP:", restore_acronym(dict_PPAP, "AP")
print "PA:", restore_acronym(dict_PPAP, "PA")

résultat


PP: ['pen', 'pineapple']
AP: ['apple', 'pen']
PA: []

Puisque PP et AP sont inclus dans le dictionnaire, la séquence d'origine est renvoyée. Pour PA, un tableau vide, qui est la valeur par défaut, est renvoyé car il n'est pas inclus dans le dictionnaire. J'ai eu les résultats que je voulais.

Cependant, l'utilisation d'une fonction écrite de cette manière peut avoir des résultats surprenants. Récupérons le tableau vide par défaut de cette fonction et ajoutons quelques éléments comme suit:

Python


my_list = restore_acronym(dict_PPAP, "PA")
print my_list

my_list.append("pico")
my_list.append("taro")
print my_list

résultat


[]
['pico', 'taro']

Cette opération semble bien, mais elle a des conséquences surprenantes. Après cette opération, essayez d'obtenir la valeur par défaut en spécifiant une clé qui n'est pas incluse dans le dictionnaire (par exemple, BANANA).

Python


print "BANANA:", restore_acronym(dict_PPAP, "BANANA")

résultat


BANANA: ['pico', 'taro']

Vous pouvez voir que l'effet de l'opération précédente reste dans la valeur par défaut.

Cela est dû au fait que les arguments par défaut des fonctions Python ne sont évalués qu'une seule fois lorsque le module est chargé.

Par exemple, considérez la fonction suivante.

Python


from datetime import datetime

def my_log(message, timestamp = datetime.now()):
    print "{timestamp}: {message}".format(timestamp = timestamp, message = message)

Cette fonction est destinée à afficher l'horodatage à ce moment lors de la sortie du message de journal. Cependant, lorsque je l'exécute, cela ressemble à ceci:

Python


from time import sleep

my_log("0 sec")
sleep(1)
my_log("1 sec")

résultat


2016-12-31 23:59:59: 0 sec
2016-12-31 23:59:59: 1 sec

Le même horodatage est affiché même si 1 seconde s'est écoulée. Comme mentionné ci-dessus, l'argument par défaut n'est évalué qu'une seule fois lorsque la fonction est chargée. Par conséquent, l'argument par défaut stocke l'horodatage lorsque la fonction est chargée et l'horodatage ne change pas chaque fois que la fonction est appelée.

Pour que cette fonction fonctionne comme prévu, utilisez None et modifiez-la comme suit:

Python


def my_log2(message, timestamp = None):
    if timestamp is None:
        timestamp = datetime.now()
    print "{timestamp}: {message}".format(timestamp = timestamp, message = message)

my_log2("0 sec")
sleep(1)
my_log2("1 sec")

résultat


2016-12-31 23:59:59: 0 sec
2017-01-01 00:00:00: 1 sec

En spécifiant None comme argument par défaut et en introduisant` timestamp = datetime.now () ʻà l'intérieur de la fonction, l'horodatage est obtenu pour chaque appel à la fonction.

Cela a résolu le problème d'horodatage.

Revenons maintenant au problème PPAP. Dans ce cas, puisqu'un tableau vide a été spécifié comme argument par défaut, un objet tableau vide a été créé lorsque la fonction a été chargée et cet objet a été réutilisé, le problème était donc que les modifications apportées à ce tableau vide étaient enregistrées. Cela peut également être résolu en spécifiant «Aucun» comme argument par défaut.

Python


def restore_acronym2(dic, key, default = None):
    if default is None:
        default = []
    if key in dic:
        return dic[key]
    else:
        return default

Désormais, chaque fois que vous appelez une fonction, un tableau vide d'objets sera créé. En fait, obtenir le tableau vide par défaut et y ajouter des éléments n'a aucun effet sur le prochain appel par défaut.

Python


my_list2 = restore_acronym2(dict_PPAP, "PA")
print my_list2

my_list2.append("pico")
my_list2.append("taro")
print my_list2

print "BANANA:", restore_acronym2(dict_PPAP, "BANANA")

résultat


[]
['pico', 'taro']
BANANA: []

Notez qu'en Python, définir un objet mutable comme argument par défaut d'une fonction peut provoquer des bogues inattendus.

Enjoy!

Recommended Posts

Précautions lors de l'attribution de valeurs par défaut aux arguments dans les définitions de fonctions Python
Précautions lors du décapage d'une fonction en python
Choses à surveiller lors de l'utilisation d'arguments par défaut en Python
Enregistrer automatiquement les arguments de fonction dans argparse en Python
[Python] Précautions lors de l'affectation de valeurs à des tableaux multidimensionnels
Précautions lors de l'utilisation de Pit avec Python
Notation inclusive dans l'argument de la fonction Python
Précautions lors du passage de def aux fonctions triées et groupby en Python? ??
Pour définir le codage par défaut sur utf-8 en python
Comment recevoir des arguments de ligne de commande en Python
Précautions lors du traitement des structures de contrôle dans Python 2.6
Erreur lors de la tentative d'installation de psycopg2 en Python
Comment prendre plusieurs arguments lors d'un traitement parallèle à l'aide du multitraitement en python
À propos des arguments de fonction (python)
Points à garder à l'esprit lors du développement d'un robot d'exploration en Python
Obtenez des variables d'environnement en Python, sinon définissez les valeurs par défaut
Précautions lors du traitement du type ROS MultiArray en Python
Points à garder à l'esprit lors de la copie de listes Python
Conseils et précautions lors du portage des programmes MATLAB vers Python
Définissez les arguments mot-clés du constructeur sur les attributs fictifs en Python
Choses à noter lors de l'initialisation d'une liste en Python
Python: à propos des arguments de fonction
Échange de valeurs en Python
python Spécifie la fonction à exécuter lorsque le programme se termine
Comment quitter lors de l'utilisation de Python dans Terminal (Mac)
Exécuter la fonction Python à partir de Powershell (comment passer des arguments)
Points à garder à l'esprit lors du traitement des chaînes en Python2
[Python] Comment afficher les valeurs de liste dans l'ordre
Quand les arguments par défaut seront-ils liés en python? Lorsque les variables sont liées dans l'évaluation différée de la fermeture.
Points à garder à l'esprit lors du traitement des chaînes en Python 3
Je veux faire quelque chose avec Python à la fin
[Petite histoire] Une mesure minutieuse lorsque vous devez exécuter une fonction avant l'importation en Python
Comment échantillonner à partir de n'importe quelle fonction de densité de probabilité en Python
Pour renvoyer char * dans une fonction de rappel à l'aide de ctypes en Python
Méthode d'écriture pratique lors de l'ajout continu à la liste en Python
Comment spécifier des arguments de ligne de commande lors du débogage avec PyCharm
Que faire lorsque "SSL: CERTIFICATE_VERIFY_FAILED _ssl.c: 1056" apparaît en Python
J'ai essayé d'implémenter la fonction d'envoi de courrier en Python
[Introduction à Udemy Python3 + Application] 50. Arguments de position, arguments de mots-clés et arguments par défaut
Précautions lors de l'utilisation de Python avec AtCoder
Précautions lors du changement d'heure Unix en type datetime dans les pandas
Choses à garder à l'esprit lors de l'utilisation de cgi avec python.
[Introduction à Udemy Python3 + Application] 51. Soyez prudent avec les arguments par défaut
Covector pour penser en fonction
Créer une fonction en Python
Pour vider stdout en Python
Utiliser la fonction de rappel en Python
Fonction ntile (décile) en python
Connectez-vous au site Web en Python
Recevoir des arguments d'exécution dans Python 2.7
Attention lorsque os.mkdir en Python
Dessiner la fonction Yin en python
Parler avec Python [synthèse vocale]
Fonction immédiate (lie) en python
Comment développer en Python
Transférer les valeurs des paramètres en Python
Publier sur Slack en Python
Comment ne pas échapper au japonais en traitant avec JSON en Python