Chao ... †
Ich wurde kürzlich von unbeabsichtigtem Verhalten mit Pythons Standardargumentwerten geplagt, daher möchte ich hier Informationen austauschen, damit ich nicht dieselben Fehler wiederhole. Diese Umgebung ist Python 3.7.7 und 3.8.3.
Bezieht sich im folgenden Code auf "dt = datetime.now ()".
from datetime import datetime
def show_second(dt=datetime.now()):
print(dt.second)
Ich habe mit dem vorherigen Code herumgespielt, um die Funktion "show_second" einmal aufzurufen und dann drei Sekunden später die Funktion "show_second" erneut aufzurufen.
import time
from datetime import datetime
def show_second(dt=datetime.now()):
print(dt.second)
show_second() #=> 23
time.sleep(3)
show_second() #=> 23
Was meinst du dann? Obwohl ich 3 Sekunden geschlafen habe, war der Wert, der beim zweiten Aufruf der Funktion show_second
gedruckt wurde, der gleiche wie vor 3 Sekunden ...! ?? Hat die Zeit angehalten? die Welt? ?? ?? Verwenden Sie einen neuen Stand? ?? ??
Als ich das Python-Dokument las, was dies bedeutet, fand ich die folgende Beschreibung.
Der Standardargumentwert wird bei der Ausführung der Funktionsdefinition von links nach rechts ausgewertet. Dies bedeutet, dass der Standardargumentausdruck nur einmal ausgewertet wird, wenn die Funktion definiert ist und für jeden Aufruf derselbe "berechnete" Wert verwendet wird. from: https://docs.python.org/ja/3/reference/compound_stmts.html#function-definitions
Mit anderen Worten, der Standardargumentwert wird einmal ausgewertet, wenn die Funktion definiert wird, das Ergebnis wird im Speicher gespeichert, und danach, wenn der Standardargumentwert verwendet wird, unabhängig davon, wie oft die Funktion aufgerufen wird, wird das Auswertungsergebnis zum Zeitpunkt der Funktionsdefinition verwendet. Es scheint, dass es ein Mechanismus ist.
Daher ist es gefährlich, etwas wie "datetime.now ()" zu verwenden, das bei jedem Aufruf ein anderes Ergebnis liefert, und / oder etwas, das Echtzeitleistung als Standardargumentwert erfordert
Ebenso scheint es, dass Sie vorsichtig sein müssen, wenn Sie eine Liste oder ein Wörterbuch als Standardargumentwert angeben. (Verwendung und Vorsichtsmaßnahmen für Standardargumente in Python-Funktionen | note.nkmk.me)
Anschließend müssen Sie "None" auf den Standardargumentwert setzen. Wenn dies "None" ist, ersetzen Sie den Wert, den Sie ursprünglich als Standardargumentwert festlegen wollten.
Unten ist der Beispielcode.
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
Deshalb habe ich darüber gesprochen, auf die Standardargumentwerte von Python zu achten.
Recommended Posts