Wenn Sie den Beispielcode veröffentlichen, veröffentlichen Sie das Ergebnis der Ausführung in der folgenden Ausführungsumgebung. Wir werden versuchen, es in einer Form bereitzustellen, die so fehlerfrei wie möglich ist. Bitte verzeihen Sie uns, wenn es nicht funktioniert oder falsch ist.
Was geben Sie zurück, wenn etwas Unerwartetes passiert, wenn Sie es innerhalb einer Funktion verarbeiten? Ich habe "None" zurückgegeben, bis ich das wusste. Zum Beispiel der folgende Code.
#Schlechtes Beispiel (Rückgabe Keine, wenn unerwartet)
from datetime import datetime
def parse_datetimes(datetime_string_list):
result = []
for datetime_string in datetime_string_list:
try:
result.append(datetime.strptime(datetime_string, "%Y-%m-%d"))
except (ValueError, TypeError):
return None
return result
>>> print(parse_datetimes(["2020-09-22"]))
[datetime.datetime(2020, 9, 22, 0, 0)]
>>> print(parse_datetimes([]))
[]
>>> print(parse_datetimes(["hoge"]))
None
Diese Funktion akzeptiert eine Liste von Zeichenfolgen, die das Datum als Eingabe darstellen, und gibt eine Liste zurück, die in den Datums- / Uhrzeittyp konvertiert wurde, wenn die Analyse erfolgreich war, und "Keine", wenn dies fehlschlägt. Auf den ersten Blick sieht es gut aus, aber es gibt zwei Probleme damit.
Um diese Probleme zu vermeiden, ** lösen Sie eine Ausnahme aus, wenn innerhalb der Funktion etwas Unerwartetes passiert **.
#Gutes Beispiel (Auslösen einer Ausnahme, wenn unerwartet)
from datetime import datetime
class MyError(Exception):
def __init__(self, message):
self.message = message
def parse_datetimes(datetime_string_list):
result = []
for datetime_string in datetime_string_list:
try:
result.append(datetime.strptime(datetime_string, "%Y-%m-%d"))
except (ValueError, TypeError):
raise MyError(f"Der eingegebene Wert ist ungültig: {datetime_string}") #Eine Ausnahme auslösen
return result
>>> print(parse_datetimes(["2020-09-22"]))
[datetime.datetime(2020, 9, 22, 0, 0)]
>>> print(parse_datetimes([]))
[]
>>> print(parse_datetimes(["hoge"]))
...
Traceback (most recent call last):
...
__main__.MyError:Der eingegebene Wert ist ungültig: hoge
Wenn es implementiert wird, um eine Ausnahme wie oben beschrieben auszulösen, wird der Prozess nicht so fortgesetzt, wie er ist, es sei denn, die Ausnahme "MyError" wird abgefangen, und "Keine" und die leere Liste "[]" sind identisch. Es ist sicher, weil es keine Angst gibt, damit umzugehen.
Wenn Sie einen Wert für das Argument verwenden möchten, und wenn nicht, verwenden Sie den Standardwert. In einem solchen Fall ist es zweckmäßig, das Standardargument festzulegen. Zum Beispiel der folgende Code.
#Dies ist ein schlechtes Beispiel
def square(value, result_list=[]):
result_list.append(value ** 2)
return result_list
Diese Funktion fügt das Quadrat von "Wert" zu "Ergebnisliste" hinzu und gibt es zurück. Was die Gefühle derer betrifft, die dies umgesetzt haben,
result_list
eine Liste angegeben ist, geben Sie bitte das Ergebnis in dieser Liste zurück.result_list
angeben, geben Sie das Ergebnis bitte in einer leeren Liste zurück.Ich denke du denkst.
# result_Wenn Sie eine Liste angeben, wird das Ergebnis in dieser Liste zurückgegeben.
>>> result_list = [1, 4]
>>> result_list = square(3, result_list)
>>> print(result_list)
[1, 4, 9]
# result_Wenn keine Liste angegeben ist, wird das Ergebnis in der leeren Liste zurückgegeben.
>>> result_list = square(3)
>>> print(result_list)
[9]
Es sieht so aus, als gäbe es überhaupt kein Problem, oder? Aber danach passiert etwas Seltsames.
>>> result_list = square(1)
>>> print(result_list)
[9, 1] #Das?[1]Sollte zurückgegeben werden? ??
>>> result_list = square(2)
print(result_list)
[9, 1, 4] #Das? Warum gibt es 3 Werte? ??
damit. Wenn Sie es nicht wissen, werden Sie mit solch einem mysteriösen Verhalten enden.
Tatsächlich ** [Standardargumente werden beim Laden des Moduls nur einmal ausgewertet, nicht bei jedem Aufruf der Funktion](https://docs.python.org/ja/3/ faq / programmierung.html # warum-sind-Standardwerte-geteilt-zwischen-Objekten) **. Wenn Sie daher eine leere Liste "[]" als Standardargument angeben, wird die leere Liste immer mehr "angehängt", und der Inhalt der Liste wird jedes Mal erhöht, wenn Sie sie wie oben beschrieben aufrufen. ..
Es ist immer noch gut, wenn Sie dies wissen und es verwenden, aber es ist kein Verhalten, das jeder kennt. Vermeiden Sie daher am besten, eine leere Liste oder ein leeres Wörterbuch als Standardargument anzugeben. Schreiben Sie stattdessen:
#Gutes Beispiel
def square(value, result_list=None):
if result_list is None:
result_list = [] #Wenn Sie hier initialisieren, wird es jedes Mal zur leeren Liste hinzugefügt
result_list.append(value ** 2)
return result_list
Wenn wie oben implementiert, wenn "result_list" nicht angegeben ist, wird die leere Liste mit dem Ergebnis zurückgegeben.
>>> result_list = square(3)
>>> print(result_list)
[9]
>>> result_list = square(1)
>>> print(result_list)
[1]
>>> result_list = square(2)
>>> print(result_list)
[4]
Übrigens kann je nach IDE eine Warnung ausgegeben werden. Antworten Sie daher unbedingt, wenn eine Warnung ausgegeben wird. PyCharm gab die folgende Warnung aus.
Wissen Sie plötzlich, was der folgende Code bedeutet?
def safe_division(numerator, denominator, /, hoge, *, ignore_overflow, ignore_zero_division):
...
Sie fragen sich vielleicht: "Warum steht" / "oder" * "im Argument?" Dies sind ["Nur-Position-Argumente (auf der linken Seite von" / ")" und "Nur-Schlüsselwort-Argumente (auf der rechten Seite von" * "), die aus Python 3.8 hinzugefügt wurden"](https://docs.python.org/ja/ Es wird mit 3 (glossary.html # term-parameter) geschrieben.
Was bedeutet das?
/
(Zähler
und Nenner
im obigen Beispiel) sind ** Nur-Position-Argumente **.
--Position-only-Argumente können nur beim Aufrufen einer Funktion als Positionsargumente angegeben werden (dh sie können nicht als Schlüsselwortargumente angegeben werden).
--Mit anderen Worten
--Dieser Aufruf ist OK: safe_division (3, 2, ...)
--Dieser Aufruf lautet NG: safe_division (Zähler = 3, Nenner = 2, ...)
*
(ignore_overflow
und ignore_zero_division
im obigen Beispiel) sind ** Nur-Schlüsselwort-Argumente **.safe_division (..., ignore_overflow = True, ignore_zero_division = False)
--Dieser Aufruf lautet NG: safe_division (..., True, False)
/
und auf der linken Seite von *
(hoge
im obigen Beispiel) entweder als Positionsargumente oder als Schlüsselwortargumente angegeben werden.
―― Mit anderen Worten, Sie können wie zuvor anrufen
--Dieser Aufruf ist OK: safe_division (...," a ", ...)
--Dieser Aufruf ist auch OK: safe_division (..., hoge =" a ", ...)
Ich denke, die Vorteile der Verwendung von Nur-Position-Argumenten und Nur-Schlüsselwort-Argumenten sind folgende.
ignore_overflow
ist True
! Sie können es zwingen, dies zu erkennen und das Argument anzugeben
--So können Sie den häufigen Fehler "Ich wollte" ignore_overflow "auf" True "setzen, aber ich habe" True "für" ignore_zero_division "angegeben!" Reduzieren.Das Schreiben von "/" oder "*" in das Argument mag zunächst seltsam erscheinen, aber wie oben erwähnt, hat es die Vorteile, daher ist es besser, es nach Bedarf zu verwenden. Es wird jedoch nicht funktionieren, wenn es weniger als Python 3.8 ist. Seien Sie also vorsichtig!
Basierend auf dem Inhalt von Kapitel 3
Recommended Posts