⚠️ Achten Sie auf die Standardargumentwerte von Python ⚠️

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.

Was ist der Standardargumentwert?

Bezieht sich im folgenden Code auf "dt = datetime.now ()".

from datetime import datetime


def show_second(dt=datetime.now()):
    print(dt.second)

Python-Standardargumentwertfalle

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? ?? ??

Verhalten der Standardargumentwerte von Python

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)

Gegenmaßnahmen für Python-Standardargumentwerte

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

⚠️ Achten Sie auf die Standardargumentwerte von Python ⚠️
Seien Sie vorsichtig mit Pythons Append-Methode
[Einführung in Udemy Python3 + Application] 51. Seien Sie vorsichtig mit Standardargumenten
Seien Sie vorsichtig mit einfachen Methodenreferenzen
(Hinweis) Seien Sie vorsichtig mit Python Argparse
Seien Sie vorsichtig, wenn Sie CakePHP3 mit PHP7.2 ausführen
Ich wollte vorsichtig mit dem Verhalten der Standardargumente von Python sein
Seien Sie vorsichtig, wenn Sie mit gzip-komprimierten Textdateien arbeiten
Seien Sie vorsichtig beim Lesen von Daten mit Pandas (geben Sie dtype an)
Python-Standardargumentfalle
[Python3] Sei vorsichtig beim Strippen (Strip, Lstrip, Rstrip)