Der einfachste Weg, dies zu erreichen, besteht darin, die input
Methode in eine while-Schleife zu setzen. Verwenden continue
Sie diese Option, wenn Sie schlechte Eingaben erhalten, und break
aus der Schleife, wenn Sie zufrieden sind.
Wenn Ihre Eingabe eine Ausnahme auslösen könnte
Verwenden Sie try
undexcept
, um zu erkennen, wann der Benutzer Daten eingibt, die nicht analysiert werden können.
while True:
try:
# Note: Python 2.x users should use raw_input, the equivalent of 3.x's input
age = int(input("Please enter your age: "))
except ValueError:
print("Sorry, I didn't understand that.")
#better try again... Return to the start of the loop
continue
else:
#age was successfully parsed!
#we're ready to exit the loop.
break
if age >= 18:
print("You are able to vote in the United States!")
else:
print("You are not able to vote in the United States.")
Implementieren Ihrer eigenen Validierungsregeln
Wenn Sie Werte ablehnen möchten, die Python erfolgreich analysieren kann, können Sie Ihre eigene Validierungslogik hinzufügen.
while True:
data = input("Please enter a loud message (must be all caps): ")
if not data.isupper():
print("Sorry, your response was not loud enough.")
continue
else:
#we're happy with the value given.
#we're ready to exit the loop.
break
while True:
data = input("Pick an answer from A to D:")
if data.lower() not in ('a', 'b', 'c', 'd'):
print("Not an appropriate choice.")
else:
break
Kombination von Ausnahmebehandlung und benutzerdefinierter Validierung
Beide oben genannten Techniken können zu einer Schleife kombiniert werden.
while True:
try:
age = int(input("Please enter your age: "))
except ValueError:
print("Sorry, I didn't understand that.")
continue
if age < 0:
print("Sorry, your response must not be negative.")
continue
else:
#age was successfully parsed, and we're happy with its value.
#we're ready to exit the loop.
break
if age >= 18:
print("You are able to vote in the United States!")
else:
print("You are not able to vote in the United States.")
Alles in einer Funktion zusammenfassen
Wenn Sie Ihren Benutzer nach vielen verschiedenen Werten fragen müssen, kann es hilfreich sein, diesen Code in eine Funktion einzufügen, damit Sie ihn nicht jedes Mal neu eingeben müssen.
def get_non_negative_int(prompt):
while True:
try:
value = int(input(prompt))
except ValueError:
print("Sorry, I didn't understand that.")
continue
if value < 0:
print("Sorry, your response must not be negative.")
continue
else:
break
return value
age = get_non_negative_int("Please enter your age: ")
kids = get_non_negative_int("Please enter the number of children you have: ")
salary = get_non_negative_int("Please enter your yearly earnings, in dollars: ")
Alles zusammenfügen
Sie können diese Idee erweitern, um eine sehr allgemeine Eingabefunktion zu erstellen:
def sanitised_input(prompt, type_=None, min_=None, max_=None, range_=None):
if min_ is not None and max_ is not None and max_ < min_:
raise ValueError("min_ must be less than or equal to max_.")
while True:
ui = input(prompt)
if type_ is not None:
try:
ui = type_(ui)
except ValueError:
print("Input type must be {0}.".format(type_.__name__))
continue
if max_ is not None and ui > max_:
print("Input must be less than or equal to {0}.".format(max_))
elif min_ is not None and ui < min_:
print("Input must be greater than or equal to {0}.".format(min_))
elif range_ is not None and ui not in range_:
if isinstance(range_, range):
template = "Input must be between {0.start} and {0.stop}."
print(template.format(range_))
else:
template = "Input must be {0}."
if len(range_) == 1:
print(template.format(*range_))
else:
expected = " or ".join((
", ".join(str(x) for x in range_[:-1]),
str(range_[-1])
))
print(template.format(expected))
else:
return ui
Bei Verwendung wie:
age = sanitised_input("Enter your age: ", int, 1, 101)
answer = sanitised_input("Enter your answer: ", str.lower, range_=('a', 'b', 'c', 'd'))
Häufige Fallstricke und warum Sie sie vermeiden sollten
Die redundante Verwendung redundanter input
Anweisungen
Diese Methode funktioniert, wird aber allgemein als schlechter Stil angesehen:
data = input("Please enter a loud message (must be all caps): ")
while not data.isupper():
print("Sorry, your response was not loud enough.")
data = input("Please enter a loud message (must be all caps): ")
Es mag anfangs attraktiv aussehen, weil es kürzer als die while True
Methode ist, aber es verstößt gegen das Don't Repeat Yourself- Prinzip der Softwareentwicklung. Dies erhöht die Wahrscheinlichkeit von Fehlern in Ihrem System. Was passiert , wenn Sie durch die Umstellung auf 2,7 zurückzuportieren wollen input
zu raw_input
, aber aus Versehen nur zuerst das ändern input
oben? Es SyntaxError
wartet nur darauf, dass es passiert.
Rekursion wird Ihren Stapel sprengen
Wenn Sie gerade etwas über Rekursion gelernt haben, könnten Sie versucht sein, sie zu verwenden, get_non_negative_int
damit Sie die while-Schleife entsorgen können.
def get_non_negative_int(prompt):
try:
value = int(input(prompt))
except ValueError:
print("Sorry, I didn't understand that.")
return get_non_negative_int(prompt)
if value < 0:
print("Sorry, your response must not be negative.")
return get_non_negative_int(prompt)
else:
return value
Dies scheint die meiste Zeit gut zu funktionieren, aber wenn der Benutzer genügend oft ungültige Daten eingibt, wird das Skript mit a beendet RuntimeError: maximum recursion depth exceeded
. Sie mögen denken, "kein Dummkopf würde 1000 Fehler hintereinander machen", aber Sie unterschätzen den Einfallsreichtum von Dummköpfen!
input
pro Schleife haben und die Schleife wird sehr kurz, aber der Zustand könnte ziemlich lang werden ...Warum sollten Sie eine machen
while True
und dann aus dieser Schleife ausbrechen, während Sie Ihre Anforderungen auch einfach in die while-Anweisung einfügen können, da Sie nur aufhören möchten, sobald Sie das Alter erreicht haben?Dies würde Folgendes ergeben:
Dies wird funktionieren, da das Alter niemals einen Wert haben wird, der keinen Sinn ergibt und der Code der Logik Ihres "Geschäftsprozesses" folgt.
quelle
Obwohl die akzeptierte Antwort erstaunlich ist. Ich möchte auch einen kurzen Hack für dieses Problem teilen. (Dies kümmert sich auch um das negative Altersproblem.)
PS Dieser Code ist für Python 3.x.
quelle
def
stattdessen einfach .def f(age):
ist viel klarer alsf = lambda age:
Also habe ich kürzlich mit etwas Ähnlichem herumgespielt und mir die folgende Lösung ausgedacht, die eine Methode verwendet, um Eingaben zu erhalten, die Junk ablehnen, bevor sie überhaupt auf logische Weise überprüft werden.
read_single_keypress()
Mit freundlicher Genehmigung von https://stackoverflow.com/a/6599441/4532996Das komplette Modul finden Sie hier .
Beispiel:
Beachten Sie, dass diese Implementierung standardmäßig geschlossen wird, sobald etwas gelesen wird, das keine Ziffer ist. Ich habe danach nicht die Eingabetaste gedrückt
a
, aber ich musste nach den Zahlen.Sie können dies mit der
thismany()
Funktion im selben Modul zusammenführen, um beispielsweise nur drei Ziffern zuzulassen.quelle
Funktionaler Ansatz oder " Look Mom No Loops! ":
oder wenn Sie möchten, dass eine "schlechte Eingabe" von einer Eingabeaufforderung wie in anderen Antworten getrennt wird:
Wie funktioniert es?
itertools.chain
unditertools.repeat
erzeugt einen Iterator, der"Enter a number: "
einmal und"Not a number! Try again: "
unendlich oft Zeichenfolgen liefert :replies = map(input, prompts)
- Hiermap
werden alleprompts
Zeichenfolgen aus dem vorherigen Schritt auf dieinput
Funktion angewendet. Z.B:filter
undstr.isdigit
filtern die Zeichenfolgen heraus, die nur Ziffern enthalten: Und um nur die erste Nur-Ziffern-Zeichenfolge zu erhalten, die wir verwendennext
.Andere Validierungsregeln:
String-Methoden: Natürlich können Sie auch andere String-Methoden verwenden
str.isalpha
, um nur alphabetische Strings oderstr.isupper
nur Großbuchstaben zu erhalten. Die vollständige Liste finden Sie in den Dokumenten .Mitgliedschaftstests:
Es gibt verschiedene Möglichkeiten, dies durchzuführen. Eine davon ist die Verwendung der folgenden
__contains__
Methode:Zahlenvergleich:
Es gibt nützliche Vergleichsmethoden, die wir hier verwenden können. Zum Beispiel für
__lt__
(<
):Wenn Sie keine Dunder-Methoden verwenden möchten (Dunder = doppelter Unterstrich), können Sie jederzeit Ihre eigene Funktion definieren oder die aus dem
operator
Modul verwenden.Pfadexistenz:
Hier kann man die
pathlib
Bibliothek und ihrePath.exists
Methode verwenden:Begrenzung der Anzahl der Versuche:
Wenn Sie einen Benutzer nicht foltern möchten, indem Sie ihn unendlich oft nach etwas fragen, können Sie in einem Anruf von ein Limit angeben
itertools.repeat
. Dies kann mit der Bereitstellung eines Standardwerts für dienext
Funktion kombiniert werden:Eingabedaten vorverarbeiten:
Manchmal möchten wir eine Eingabe nicht ablehnen, wenn der Benutzer sie versehentlich IN GROSSBUCHSTABEN oder mit einem Leerzeichen am Anfang oder Ende der Zeichenfolge angegeben hat. Um diese einfachen Fehler zu berücksichtigen, können wir die Eingabedaten durch Anwenden
str.lower
undstr.strip
Methoden vorverarbeiten . Für den Fall des Mitgliedschaftstests sieht der Code beispielsweise folgendermaßen aus:Im Fall , wenn Sie viele Funktionen nutzen für die Vorverarbeitung haben, könnte es einfacher sein , eine Funktion zu verwenden , um eine Durchführung Funktion Zusammensetzung . Verwenden Sie zum Beispiel die von hier :
Validierungsregeln kombinieren:
In einem einfachen Fall, wenn das Programm beispielsweise nach einem Alter zwischen 1 und 120 Jahren fragt, kann man einfach ein weiteres hinzufügen
filter
:Wenn es jedoch viele Regeln gibt, ist es besser, eine Funktion zu implementieren, die eine logische Konjunktion ausführt . Im folgenden Beispiel werde ich von hier aus ein fertiges verwenden :
Wenn jemand für jeden fehlgeschlagenen Fall eine benutzerdefinierte Nachricht benötigt, gibt es leider keinen ziemlich funktionalen Weg. Zumindest konnte ich keinen finden.
quelle
Verwenden von Click :
Click ist eine Bibliothek für Befehlszeilenschnittstellen und bietet Funktionen zum Abfragen einer gültigen Antwort von einem Benutzer.
Einfaches Beispiel:
Beachten Sie, wie der Zeichenfolgenwert automatisch in einen Float konvertiert wurde.
Überprüfen, ob ein Wert innerhalb eines Bereichs liegt:
Es werden verschiedene benutzerdefinierte Typen bereitgestellt. Um eine Zahl in einem bestimmten Bereich zu erhalten, können wir verwenden
IntRange
:Wir können auch nur eine der Grenzen angeben
min
odermax
:Mitgliedschaftstests:
Mit
click.Choice
Art. Standardmäßig wird bei dieser Prüfung zwischen Groß- und Kleinschreibung unterschieden.Arbeiten mit Pfaden und Dateien:
Mit einem
click.Path
Typ können wir nach vorhandenen Pfaden suchen und diese auch auflösen:Das Lesen und Schreiben von Dateien kann erfolgen durch
click.File
:Andere Beispiele:
Passwort Bestätigung:
Standardwerte:
In diesem Fall erhalten Sie durch einfaches Drücken Enter(oder einer beliebigen Taste) ohne Eingabe eines Werts einen Standardwert:
quelle
quelle
Aufbauend auf den hervorragenden Vorschlägen von Daniel Q und Patrick Artner finden Sie hier eine noch allgemeinere Lösung.
Ich habe mich für explizite
if
undraise
Anweisungen anstelle von entschiedenassert
, da die Überprüfung von Zusicherungen möglicherweise deaktiviert ist, während die Validierung immer aktiviert sein sollte, um Robustheit zu gewährleisten.Dies kann verwendet werden, um verschiedene Arten von Eingaben mit unterschiedlichen Validierungsbedingungen zu erhalten. Zum Beispiel:
Oder um die ursprüngliche Frage zu beantworten:
quelle
Probier diese:-
quelle
Während ein
try
/except
Block funktioniert, wäre eine viel schnellere und sauberere Möglichkeit, diese Aufgabe zu erfüllen, die Verwendungstr.isdigit()
.quelle
Gute Frage! Sie können dazu den folgenden Code ausprobieren. =)
Dieser Code verwendet ast.literal_eval () , um den Datentyp der Eingabe (
age
) zu ermitteln. Dann folgt der folgende Algorithmus:Hier ist der Code.
quelle
Sie können jederzeit eine einfache if-else-Logik anwenden und
if
Ihrem Code zusammen mit einerfor
Schleife eine weitere Logik hinzufügen .Dies wird ein unendliches Klo sein und Sie werden gebeten, das Alter auf unbestimmte Zeit einzugeben.
quelle
Sie können eine allgemeinere Logik schreiben, damit Benutzer nur eine bestimmte Anzahl von Malen eingeben können, da der gleiche Anwendungsfall in vielen realen Anwendungen auftritt.
quelle
Sie können die Eingabeanweisung zu einer while True-Schleife machen, sodass sie wiederholt nach den Eingaben des Benutzers fragt, und diese Schleife dann unterbrechen, wenn der Benutzer die gewünschte Antwort eingibt. Und Sie können Try-and-Except-Blöcke verwenden, um ungültige Antworten zu verarbeiten.
Die Variable var ist nur so, dass das Programm nicht "Sie können in den USA nicht abstimmen" zurückgibt, wenn der Benutzer eine Zeichenfolge anstelle einer Ganzzahl eingibt.
quelle
Verwenden Sie die Anweisung "while", bis der Benutzer einen wahren Wert eingibt. Wenn der Eingabewert keine Zahl oder ein Nullwert ist, überspringen Sie ihn und versuchen Sie erneut zu fragen und so weiter. Zum Beispiel habe ich versucht, Ihre Frage wirklich zu beantworten. Wenn wir annehmen, dass unser Alter zwischen 1 und 150 liegt, wird der Eingabewert akzeptiert, andernfalls ist es ein falscher Wert. Zum Beenden des Programms kann der Benutzer die Taste 0 verwenden und als Wert eingeben.
quelle
Eine weitere Lösung für die Verwendung der Eingabevalidierung mithilfe einer benutzerdefinierten
ValidationError
und einer (optionalen) Bereichsvalidierung für ganzzahlige Eingaben:Verwendungszweck:
Ausgabe:
quelle
Hier ist eine sauberere, allgemeinere Lösung, die wiederholte if / else-Blöcke vermeidet: Schreiben Sie eine Funktion, die (Fehler, Fehleraufforderung) Paare in ein Wörterbuch aufnimmt, und führen Sie alle Ihre Wertprüfungen mit Zusicherungen durch.
Verwendungszweck:
quelle
Permanente Benutzereingaben mit rekursiver Funktion :
String
Ganze Zahl
und schließlich die Frage Anforderung:
quelle
Die einfache Lösung wäre:
Erläuterung des obigen Codes: Um ein gültiges Alter zu erhalten, sollte es positiv sein und nicht höher als das normale physische Alter sein, beispielsweise beträgt das Höchstalter 120 Jahre.
Dann können wir den Benutzer nach dem Alter fragen. Wenn die Alterseingabe negativ ist oder mehr als 120 beträgt, betrachten wir die Eingabe als ungültig und bitten den Benutzer, es erneut zu versuchen.
Sobald die gültige Eingabe eingegeben wurde, führen wir eine Überprüfung (unter Verwendung einer verschachtelten if-else-Anweisung) durch, ob das Alter> = 18 ist, oder umgekehrt, und drucken eine Nachricht, ob der Benutzer wahlberechtigt ist
quelle
Nehmen Sie die Eingabe als Zeichenfolge und verwenden Sie isdigit (), um zu überprüfen, ob die Eingabe nur Ziffern enthält, nicht leer, kann nicht -ve sein
quelle