Chao ... †
J'ai récemment été en proie à un comportement involontaire avec les valeurs d'argument par défaut de Python, donc j'aimerais partager des informations ici afin de ne pas répéter les mêmes erreurs. Cet environnement est Python 3.7.7 et 3.8.3.
Se réfère à «dt = datetime.now ()» dans le code ci-dessous.
from datetime import datetime
def show_second(dt=datetime.now()):
print(dt.second)
J'ai manipulé le code précédent pour appeler la fonction show_second
une fois, puis appeler à nouveau la fonction show_second
trois secondes plus tard.
import time
from datetime import datetime
def show_second(dt=datetime.now()):
print(dt.second)
show_second() #=> 23
time.sleep(3)
show_second() #=> 23
Alors qu'est-ce que tu veux dire! Même si j'ai dormi 3 secondes, la valeur imprimée lors de l'appel de la fonction show_second
pour la deuxième fois était la même qu'il y a 3 secondes ...! ?? Le temps s'est-il arrêté? le monde? ?? ?? Utilisez-vous un nouveau stand? ?? ??
Eh bien, quand j'ai lu le document Python ce que cela signifie, j'ai trouvé la description suivante.
La valeur de l'argument par défaut est évaluée de gauche à droite lorsque la définition de fonction est exécutée. Cela signifie que l'expression d'argument par défaut n'est évaluée qu'une seule fois lorsque la fonction est définie et que la même valeur «calculée» est utilisée pour chaque appel. from: https://docs.python.org/ja/3/reference/compound_stmts.html#function-definitions
En d'autres termes, la valeur de l'argument par défaut est évaluée une fois lorsque la fonction est définie, le résultat est enregistré dans la mémoire, et après cela, lorsque la valeur de l'argument par défaut est utilisée quel que soit le nombre d'appels de la fonction, le résultat de l'évaluation au moment de la définition de la fonction est utilisé. Il semble que ce soit un mécanisme.
Par conséquent, il est dangereux d'utiliser quelque chose comme datetime.now ()
qui donne un résultat différent à chaque fois que vous appelez et / ou quelque chose qui nécessite des performances en temps réel comme valeur d'argument par défaut ⚠️
De même, il semble que vous deviez être prudent lorsque vous spécifiez une liste ou un dictionnaire comme valeur d'argument par défaut. (Utilisation et précautions des arguments par défaut dans les fonctions Python | note.nkmk.me)
Ensuite, ce qu'il faut faire est de définir «Aucun» sur la valeur d'argument par défaut, et s'il s'agit de «Aucun», remplacez la valeur que vous vouliez à l'origine définir comme valeur d'argument par défaut.
Voici l'exemple de code.
import time
from datetime import datetime
def show_second(dt=None):
if dt is None:
dt = datetime.now()
print(dt.second)
show_second() #=> 23
time.sleep(3)
show_second() #=> 26
C'est pourquoi je parlais de prêter attention aux valeurs d'argument par défaut de Python.
Recommended Posts