In Python können Argumente beim Definieren einer Funktion Standardwerte haben.
Die folgende Funktion ruft einen Wert durch Angabe eines Schlüssels für das Wörterbuch ab, gibt jedoch den Standardwert 0 zurück, wenn das Wörterbuch keinen Schlüssel enthält.
Python
def get(dic, key, default = 0):
if key in dic:
return dic[key]
else:
return default
Machen wir das.
Python
#Bereiten Sie ein Wörterbuch vor
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")
Ergebnis
pen: 2
apple: 1
banana: 0
Da Stift und Apfel im Wörterbuch enthalten sind, werden ihre Werte zurückgegeben. Da Banane nicht im Wörterbuch enthalten ist, wird der Standardwert 0 zurückgegeben.
Bisher gibt es kein Problem. Betrachten Sie nun den folgenden Fall.
Python
dict_PPAP = {"PP": ["pen", "pineapple"], "AP": ["apple", "pen"],
"PPAP": ["pen", "pineapple", "apple", "pen"]}
Dieses Wörterbuch ist ein Wörterbuch, in dem ein Array der entsprechenden Prototypen für das Akronym gespeichert ist. Schreiben wir für dieses Wörterbuch eine ähnliche Funktion wie oben.
Python
def restore_acronym(dic, key, default = []):
if key in dic:
return dic[key]
else:
return default
Ich werde es versuchen.
Python
print "PP:", restore_acronym(dict_PPAP, "PP")
print "AP:", restore_acronym(dict_PPAP, "AP")
print "PA:", restore_acronym(dict_PPAP, "PA")
Ergebnis
PP: ['pen', 'pineapple']
AP: ['apple', 'pen']
PA: []
Da PP und AP im Wörterbuch enthalten sind, wird die ursprüngliche Sequenz zurückgegeben. Für PA wird ein leeres Array zurückgegeben, das der Standardwert ist, da es nicht im Wörterbuch enthalten ist. Ich habe die gewünschten Ergebnisse erzielt.
Die Verwendung einer auf diese Weise geschriebenen Funktion kann jedoch zu überraschenden Ergebnissen führen. Lassen Sie uns das leere Standardarray aus dieser Funktion abrufen und einige Elemente wie folgt hinzufügen:
Python
my_list = restore_acronym(dict_PPAP, "PA")
print my_list
my_list.append("pico")
my_list.append("taro")
print my_list
Ergebnis
[]
['pico', 'taro']
Diese Operation scheint in Ordnung zu sein, hat aber überraschende Konsequenzen. Versuchen Sie nach diesem Vorgang, den Standardwert abzurufen, indem Sie einen Schlüssel angeben, der nicht im Wörterbuch enthalten ist (z. B. BANANA).
Python
print "BANANA:", restore_acronym(dict_PPAP, "BANANA")
Ergebnis
BANANA: ['pico', 'taro']
Sie können sehen, dass der Effekt der vorherigen Operation im Standardwert bleibt.
Dies liegt daran, dass die Standardargumente von Python-Funktionen beim Laden des Moduls nur einmal ausgewertet werden.
Betrachten Sie beispielsweise die folgende Funktion.
Python
from datetime import datetime
def my_log(message, timestamp = datetime.now()):
print "{timestamp}: {message}".format(timestamp = timestamp, message = message)
Diese Funktion soll den Zeitstempel zu diesem Zeitpunkt bei der Ausgabe der Protokollnachricht ausgeben. Wenn ich es jedoch tatsächlich starte, sieht es so aus:
Python
from time import sleep
my_log("0 sec")
sleep(1)
my_log("1 sec")
Ergebnis
2016-12-31 23:59:59: 0 sec
2016-12-31 23:59:59: 1 sec
Der gleiche Zeitstempel wird angezeigt, obwohl 1 Sekunde vergangen ist. Wie oben erwähnt, wird das Standardargument beim Laden der Funktion nur einmal ausgewertet. Daher speichert das Standardargument den Zeitstempel, wenn die Funktion geladen wird, und der Zeitstempel ändert sich nicht bei jedem Aufruf der Funktion.
Damit diese Funktion wie beabsichtigt funktioniert, verwenden Sie "Keine" und ändern Sie sie wie folgt:
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")
Ergebnis
2016-12-31 23:59:59: 0 sec
2017-01-01 00:00:00: 1 sec
Indem Sie "None" als Standardargument angeben und "timestamp = datetime.now ()" in die Funktion einfügen, wird der Zeitstempel für jeden Aufruf der Funktion abgerufen.
Dies löste das Zeitstempelproblem.
Kommen wir nun zum PPAP-Problem zurück. In diesem Fall wurde, da ein leeres Array als Standardargument angegeben wurde, beim Laden der Funktion ein leeres Array-Objekt erstellt und dieses Objekt wiederverwendet. Das Problem bestand also darin, dass Änderungen an diesem leeren Array gespeichert wurden. Dies kann auch behoben werden, indem "None" als Standardargument angegeben wird.
Python
def restore_acronym2(dic, key, default = None):
if default is None:
default = []
if key in dic:
return dic[key]
else:
return default
Jedes Mal, wenn Sie eine Funktion aufrufen, wird ein leeres Array von Objekten erstellt. Das Abrufen des leeren Standardarrays und das Hinzufügen von Elementen hat keine Auswirkungen auf den nächsten Standardaufruf.
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")
Ergebnis
[]
['pico', 'taro']
BANANA: []
Beachten Sie, dass das Festlegen eines veränderlichen Objekts als Standardargument einer Funktion in Python zu unerwarteten Fehlern führen kann.
Enjoy!
Recommended Posts