Bitten Sie den Benutzer um Eingabe, bis er eine gültige Antwort gibt
Ich schreibe ein Programm, das eine Eingabe vom Benutzer akzeptiert.
#note: Python 2.7 users should use `raw_input`, the equivalent of 3.X's `input`
age = int(input("Please enter your age: "))
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.")
Das Programm funktioniert wie erwartet, solange der Benutzer aussagekräftige Daten eingibt.
C:\Python\Projects> canyouvote.py
Please enter your age: 23
You are able to vote in the United States!
Es schlägt jedoch fehl, wenn der Benutzer ungültige Daten eingibt:
C:\Python\Projects> canyouvote.py
Please enter your age: dickety six
Traceback (most recent call last):
File "canyouvote.py", line 1, in <module>
age = int(input("Please enter your age: "))
ValueError: invalid literal for int() with base 10: 'dickety six'
Anstatt abzustürzen, möchte ich, dass das Programm erneut nach der Eingabe fragt. So was:
C:\Python\Projects> canyouvote.py
Please enter your age: dickety six
Sorry, I didn't understand that.
Please enter your age: 26
You are able to vote in the United States!
Wie kann ich das Programm dazu bringen, nach gültigen Eingaben zu fragen, anstatt abzustürzen, wenn unsinnige Daten eingegeben werden?
Wie kann ich Werte wie ablehnen -1
, die int
in diesem Zusammenhang gültig , aber unsinnig sind?
Antworten
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!
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?
age = None
while age is None:
input_value = input("Please enter your age: ")
try:
# try and convert the string input to a number
age = int(input_value)
except ValueError:
# tell the user off
print("{input} is not a number, please enter a number only".format(input=input_value))
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.")
Dies würde Folgendes ergeben:
Please enter your age: *potato*
potato is not a number, please enter a number only
Please enter your age: *5*
You are not able to vote in the United States.
Dies wird funktionieren, da das Alter niemals einen Wert haben wird, der keinen Sinn ergibt, und der Code der Logik Ihres "Geschäftsprozesses" folgt.
Obwohl die akzeptierte Antwort erstaunlich ist. Ich möchte auch einen kurzen Hack für dieses Problem teilen. (Dies behebt auch das negative Altersproblem.)
f=lambda age: (age.isdigit() and ((int(age)>=18 and "Can vote" ) or "Cannot vote")) or \
f(input("invalid input. Try again\nPlease enter your age: "))
print(f(input("Please enter your age: ")))
PS Dieser Code ist für Python 3.x.
Funktionaler Ansatz oder " Look Mom No Loops! ":
from itertools import chain, repeat
prompts = chain(["Enter a number: "], repeat("Not a number! Try again: "))
replies = map(input, prompts)
valid_response = next(filter(str.isdigit, replies))
print(valid_response)
Enter a number: a
Not a number! Try again: b
Not a number! Try again: 1
1
oder wenn Sie möchten, dass eine Meldung "schlechte Eingabe" wie in anderen Antworten von einer Eingabeaufforderung getrennt wird:
prompt_msg = "Enter a number: "
bad_input_msg = "Sorry, I didn't understand that."
prompts = chain([prompt_msg], repeat('\n'.join([bad_input_msg, prompt_msg])))
replies = map(input, prompts)
valid_response = next(filter(str.isdigit, replies))
print(valid_response)
Enter a number: a
Sorry, I didn't understand that.
Enter a number: b
Sorry, I didn't understand that.
Enter a number: 1
1
Wie funktioniert es?
-
Diese Kombination vonprompts = chain(["Enter a number: "], repeat("Not a number! Try again: "))
itertools.chain
unditertools.repeat
erzeugt einen Iterator, der"Enter a number: "
einmal und"Not a number! Try again: "
unendlich oft Zeichenfolgen liefert :for prompt in prompts: print(prompt)
Enter a number: Not a number! Try again: Not a number! Try again: Not a number! Try again: # ... and so on
replies = map(input, prompts)
- Hiermap
werden alleprompts
Zeichenfolgen aus dem vorherigen Schritt auf dieinput
Funktion angewendet. Z.B:for reply in replies: print(reply)
Enter a number: a a Not a number! Try again: 1 1 Not a number! Try again: it doesn't care now it doesn't care now # and so on...
- Wir verwenden
filter
undstr.isdigit
filtern die Zeichenfolgen heraus, die nur Ziffern enthalten:only_digits = filter(str.isdigit, replies) for reply in only_digits: print(reply)
Und um nur die erste Nur-Ziffern-Zeichenfolge zu erhalten, die wir verwendenEnter a number: a Not a number! Try again: 1 1 Not a number! Try again: 2 2 Not a number! Try again: b Not a number! Try again: # and so on...
next
.
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:from itertools import chain, repeat fruits = {'apple', 'orange', 'peach'} prompts = chain(["Enter a fruit: "], repeat("I don't know this one! Try again: ")) replies = map(input, prompts) valid_response = next(filter(fruits.__contains__, replies)) print(valid_response)
Enter a fruit: 1 I don't know this one! Try again: foo I don't know this one! Try again: apple apple
Zahlenvergleich:
Es gibt nützliche Vergleichsmethoden, die wir hier verwenden können. Zum Beispiel für__lt__
(<
):from itertools import chain, repeat prompts = chain(["Enter a positive number:"], repeat("I need a positive number! Try again:")) replies = map(input, prompts) numeric_strings = filter(str.isnumeric, replies) numbers = map(float, numeric_strings) is_positive = (0.).__lt__ valid_response = next(filter(is_positive, numbers)) print(valid_response)
Enter a positive number: a I need a positive number! Try again: -5 I need a positive number! Try again: 0 I need a positive number! Try again: 5 5.0
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 diepathlib
Bibliothek und ihrePath.exists
Methode verwenden:from itertools import chain, repeat from pathlib import Path prompts = chain(["Enter a path: "], repeat("This path doesn't exist! Try again: ")) replies = map(input, prompts) paths = map(Path, replies) valid_response = next(filter(Path.exists, paths)) print(valid_response)
Enter a path: a b c This path doesn't exist! Try again: 1 This path doesn't exist! Try again: existing_file.txt existing_file.txt
Begrenzung der Anzahl der Versuche:
Wenn Sie einen Benutzer nicht foltern möchten, indem Sie ihn unendlich oft etwas fragen, können Sie in einem Anruf von ein Limit angeben itertools.repeat
. Dies kann mit der Bereitstellung eines Standardwerts für die next
Funktion kombiniert werden:
from itertools import chain, repeat
prompts = chain(["Enter a number:"], repeat("Not a number! Try again:", 2))
replies = map(input, prompts)
valid_response = next(filter(str.isdigit, replies), None)
print("You've failed miserably!" if valid_response is None else 'Well done!')
Enter a number: a
Not a number! Try again: b
Not a number! Try again: c
You've failed miserably!
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
und str.strip
Methoden vorverarbeiten . Für den Fall des Mitgliedschaftstests sieht der Code beispielsweise folgendermaßen aus:
from itertools import chain, repeat
fruits = {'apple', 'orange', 'peach'}
prompts = chain(["Enter a fruit: "], repeat("I don't know this one! Try again: "))
replies = map(input, prompts)
lowercased_replies = map(str.lower, replies)
stripped_replies = map(str.strip, lowercased_replies)
valid_response = next(filter(fruits.__contains__, stripped_replies))
print(valid_response)
Enter a fruit: duck
I don't know this one! Try again: Orange
orange
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 :
from itertools import chain, repeat
from lz.functional import compose
fruits = {'apple', 'orange', 'peach'}
prompts = chain(["Enter a fruit: "], repeat("I don't know this one! Try again: "))
replies = map(input, prompts)
process = compose(str.strip, str.lower) # you can add more functions here
processed_replies = map(process, replies)
valid_response = next(filter(fruits.__contains__, processed_replies))
print(valid_response)
Enter a fruit: potato
I don't know this one! Try again: PEACH
peach
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
:
from itertools import chain, repeat
prompt_msg = "Enter your age (1-120): "
bad_input_msg = "Wrong input."
prompts = chain([prompt_msg], repeat('\n'.join([bad_input_msg, prompt_msg])))
replies = map(input, prompts)
numeric_replies = filter(str.isdigit, replies)
ages = map(int, numeric_replies)
positive_ages = filter((0).__lt__, ages)
not_too_big_ages = filter((120).__ge__, positive_ages)
valid_response = next(not_too_big_ages)
print(valid_response)
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 :
from functools import partial
from itertools import chain, repeat
from lz.logical import conjoin
def is_one_letter(string: str) -> bool:
return len(string) == 1
rules = [str.isalpha, str.isupper, is_one_letter, 'C'.__le__, 'P'.__ge__]
prompt_msg = "Enter a letter (C-P): "
bad_input_msg = "Wrong input."
prompts = chain([prompt_msg], repeat('\n'.join([bad_input_msg, prompt_msg])))
replies = map(input, prompts)
valid_response = next(filter(conjoin(*rules), replies))
print(valid_response)
Enter a letter (C-P): 5
Wrong input.
Enter a letter (C-P): f
Wrong input.
Enter a letter (C-P): CDE
Wrong input.
Enter a letter (C-P): Q
Wrong input.
Enter a letter (C-P): N
N
Wenn jemand für jeden fehlgeschlagenen Fall eine benutzerdefinierte Nachricht benötigt, gibt es leider keinen ziemlich funktionalen Weg. Zumindest konnte ich keinen finden.
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/4532996
def read_single_keypress() -> str:
"""Waits for a single keypress on stdin.
-- from :: https://stackoverflow.com/a/6599441/4532996
"""
import termios, fcntl, sys, os
fd = sys.stdin.fileno()
# save old state
flags_save = fcntl.fcntl(fd, fcntl.F_GETFL)
attrs_save = termios.tcgetattr(fd)
# make raw - the way to do this comes from the termios(3) man page.
attrs = list(attrs_save) # copy the stored version to update
# iflag
attrs[0] &= ~(termios.IGNBRK | termios.BRKINT | termios.PARMRK
| termios.ISTRIP | termios.INLCR | termios. IGNCR
| termios.ICRNL | termios.IXON )
# oflag
attrs[1] &= ~termios.OPOST
# cflag
attrs[2] &= ~(termios.CSIZE | termios. PARENB)
attrs[2] |= termios.CS8
# lflag
attrs[3] &= ~(termios.ECHONL | termios.ECHO | termios.ICANON
| termios.ISIG | termios.IEXTEN)
termios.tcsetattr(fd, termios.TCSANOW, attrs)
# turn off non-blocking
fcntl.fcntl(fd, fcntl.F_SETFL, flags_save & ~os.O_NONBLOCK)
# read a single keystroke
try:
ret = sys.stdin.read(1) # returns a single character
except KeyboardInterrupt:
ret = 0
finally:
# restore old state
termios.tcsetattr(fd, termios.TCSAFLUSH, attrs_save)
fcntl.fcntl(fd, fcntl.F_SETFL, flags_save)
return ret
def until_not_multi(chars) -> str:
"""read stdin until !(chars)"""
import sys
chars = list(chars)
y = ""
sys.stdout.flush()
while True:
i = read_single_keypress()
_ = sys.stdout.write(i)
sys.stdout.flush()
if i not in chars:
break
y += i
return y
def _can_you_vote() -> str:
"""a practical example:
test if a user can vote based purely on keypresses"""
print("can you vote? age : ", end="")
x = int("0" + until_not_multi("0123456789"))
if not x:
print("\nsorry, age can only consist of digits.")
return
print("your age is", x, "\nYou can vote!" if x >= 18 else "Sorry! you can't vote")
_can_you_vote()
Das komplette Modul finden Sie hier .
Beispiel:
$ ./input_constrain.py
can you vote? age : a
sorry, age can only consist of digits.
$ ./input_constrain.py
can you vote? age : 23<RETURN>
your age is 23
You can vote!
$ _
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.
Verwenden von Click :
Click ist eine Bibliothek für Befehlszeilenschnittstellen und bietet Funktionen zum Abfragen einer gültigen Antwort von einem Benutzer.
Einfaches Beispiel:
import click
number = click.prompt('Please enter a number', type=float)
print(number)
Please enter a number:
a
Error: a is not a valid floating point value
Please enter a number:
10
10.0
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
:
age = click.prompt("What's your age?", type=click.IntRange(1, 120))
print(age)
What's your age?:
a
Error: a is not a valid integer
What's your age?:
0
Error: 0 is not in the valid range of 1 to 120.
What's your age?:
5
5
Wir können auch nur eine der Grenzen angeben min
oder max
:
age = click.prompt("What's your age?", type=click.IntRange(min=14))
print(age)
What's your age?:
0
Error: 0 is smaller than the minimum valid value 14.
What's your age?:
18
18
Mitgliedschaftstests:
Mit click.Choice
Art. Standardmäßig wird bei dieser Prüfung zwischen Groß- und Kleinschreibung unterschieden.
choices = {'apple', 'orange', 'peach'}
choice = click.prompt('Provide a fruit', type=click.Choice(choices, case_sensitive=False))
print(choice)
Provide a fruit (apple, peach, orange):
banana
Error: invalid choice: banana. (choose from apple, peach, orange)
Provide a fruit (apple, peach, orange):
OrAnGe
orange
Arbeiten mit Pfaden und Dateien:
Mit einem click.Path
Typ können wir nach vorhandenen Pfaden suchen und diese auch auflösen:
path = click.prompt('Provide path', type=click.Path(exists=True, resolve_path=True))
print(path)
Provide path:
nonexistent
Error: Path "nonexistent" does not exist.
Provide path:
existing_folder
'/path/to/existing_folder
Das Lesen und Schreiben von Dateien kann erfolgen durch click.File
:
file = click.prompt('In which file to write data?', type=click.File('w'))
with file.open():
file.write('Hello!')
# More info about `lazy=True` at:
# https://click.palletsprojects.com/en/7.x/arguments/#file-opening-safety
file = click.prompt('Which file you wanna read?', type=click.File(lazy=True))
with file.open():
print(file.read())
In which file to write data?:
# <-- provided an empty string, which is an illegal name for a file
In which file to write data?:
some_file.txt
Which file you wanna read?:
nonexistent.txt
Error: Could not open file: nonexistent.txt: No such file or directory
Which file you wanna read?:
some_file.txt
Hello!
Andere Beispiele:
Passwort Bestätigung:
password = click.prompt('Enter password', hide_input=True, confirmation_prompt=True)
print(password)
Enter password:
······
Repeat for confirmation:
·
Error: the two entered values do not match
Enter password:
······
Repeat for confirmation:
······
qwerty
Standardwerte:
In diesem Fall erhalten Sie durch einfaches Drücken Enter(oder einer beliebigen Taste) ohne Eingabe eines Werts einen Standardwert:
number = click.prompt('Please enter a number', type=int, default=42)
print(number)
Please enter a number [42]:
a
Error: a is not a valid integer
Please enter a number [42]:
42
def validate_age(age):
if age >=0 :
return True
return False
while True:
try:
age = int(raw_input("Please enter your age:"))
if validate_age(age): break
except ValueError:
print "Error: Invalid age."
Aufbauend auf den hervorragenden Vorschlägen von Daniel Q und Patrick Artner finden Sie hier eine noch allgemeinere Lösung.
# Assuming Python3
import sys
class ValidationError(ValueError): # thanks Patrick Artner
pass
def validate_input(prompt, cast=str, cond=(lambda x: True), onerror=None):
if onerror==None: onerror = {}
while True:
try:
data = cast(input(prompt))
if not cond(data): raise ValidationError
return data
except tuple(onerror.keys()) as e: # thanks Daniel Q
print(onerror[type(e)], file=sys.stderr)
Ich habe mich für explizite if
und raise
Anweisungen anstelle von entschieden assert
, 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:
# No validation, equivalent to simple input:
anystr = validate_input("Enter any string: ")
# Get a string containing only letters:
letters = validate_input("Enter letters: ",
cond=str.isalpha,
onerror={ValidationError: "Only letters, please!"})
# Get a float in [0, 100]:
percentage = validate_input("Percentage? ",
cast=float, cond=lambda x: 0.0<=x<=100.0,
onerror={ValidationError: "Must be between 0 and 100!",
ValueError: "Not a number!"})
Oder um die ursprüngliche Frage zu beantworten:
age = validate_input("Please enter your age: ",
cast=int, cond=lambda a:0<=a<150,
onerror={ValidationError: "Enter a plausible age, please!",
ValueError: "Enter an integer, please!"})
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.")
Probier diese:-
def takeInput(required):
print 'ooo or OOO to exit'
ans = raw_input('Enter: ')
if not ans:
print "You entered nothing...!"
return takeInput(required)
## FOR Exit ##
elif ans in ['ooo', 'OOO']:
print "Closing instance."
exit()
else:
if ans.isdigit():
current = 'int'
elif set('[~!@#$%^&*()_+{}":/\']+$').intersection(ans):
current = 'other'
elif isinstance(ans,basestring):
current = 'str'
else:
current = 'none'
if required == current :
return ans
else:
return takeInput(required)
## pass the value in which type you want [str/int/special character(as other )]
print "input: ", takeInput('str')
Ja, ich bin 6 Jahre zu spät vom 🎉, aber diese Frage verdient eine aktuellere Antwort.
Trennung von Bedenken
Ich bin ein großer Fan der Unix-Philosophie "Mach eins und mach es gut" . Bei dieser Art von Problem ist es besser, das Problem aufzuteilen
- Fragen Sie nach der Eingabe mit,
get_input
bis die Eingabe in Ordnung ist. - In
validator
Funktion validieren . Sie können verschiedene Validatoren für verschiedene Eingabeabfragen schreiben.
Nach Eingabe fragen
Es kann so einfach gehalten werden wie (Python 3+)
def myvalidator(value):
try:
value = int(value)
except ValueError:
return False
return value >= 0
def get_input(prompt, validator, on_validationerror):
while True:
value = input(prompt)
if validator(value):
return value
print(on_validationerror)
Beispiel
In [2]: get_input('Give a positive number: ', myvalidator, 'Please, try again')
Give a positive number: foobar
Please, try again
Give a positive number: -10
Please, try again
Give a positive number: 42
Out[2]: '42'
Python 3.8+ Hinweis
In Python 3.8+ können Sie den Walross-Operator verwenden
def get_input(prompt, validator, on_validationerror):
while not validator(value := input(prompt)):
print(on_validationerror)
return value
Während ein try
/ except
Block funktioniert, wäre eine viel schnellere und sauberere Möglichkeit, diese Aufgabe zu erfüllen, die Verwendung str.isdigit()
.
while True:
age = input("Please enter your age: ")
if age.isdigit():
age = int(age)
break
else:
print("Invalid number '{age}'. Try again.".format(age=age))
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.")
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:
Bitten Sie den Benutzer, ihn / sie einzugeben
age
.1.1. If
age
isfloat
oderint
Datentyp:
Überprüfen Sie, ob
age>=18
. Wennage>=18
ja, drucken Sie die entsprechende Ausgabe und beenden Sie das Programm.Überprüfen Sie, ob
0<age<18
. Wenn0<age<18
ja, drucken Sie die entsprechende Ausgabe und beenden Sie das Programm.Wenn
age<=0
ja, bitten Sie den Benutzer, erneut eine gültige Nummer für das Alter einzugeben ( dh fahren Sie mit Schritt 1 fort).1.2. Wenn dies
age
nicht der Fall istfloat
oder derint
Datentyp, bitten Sie den Benutzer, sein Alter erneut einzugeben ( dh gehen Sie zurück zu Schritt 1.)
Hier ist der Code.
from ast import literal_eval
''' This function is used to identify the data type of input data.'''
def input_type(input_data):
try:
return type(literal_eval(input_data))
except (ValueError, SyntaxError):
return str
flag = True
while(flag):
age = raw_input("Please enter your age: ")
if input_type(age)==float or input_type(age)==int:
if eval(age)>=18:
print("You are able to vote in the United States!")
flag = False
elif eval(age)>0 and eval(age)<18:
print("You are not able to vote in the United States.")
flag = False
else: print("Please enter a valid number as your age.")
else: print("Sorry, I didn't understand that.")
Sie können jederzeit eine einfache if-else-Logik anwenden und if
Ihrem Code zusammen mit einer for
Schleife eine weitere Logik hinzufügen .
while True:
age = int(input("Please enter your age: "))
if (age >= 18) :
print("You are able to vote in the United States!")
if (age < 18) & (age > 0):
print("You are not able to vote in the United States.")
else:
print("Wrong characters, the input must be numeric")
continue
Dies wird ein unendliches Klo sein und Sie werden gebeten, das Alter auf unbestimmte Zeit einzugeben.
Der folgende Code kann helfen.
age=(lambda i,f: f(i,f))(input("Please enter your age: "),lambda i,f: i if i.isdigit() else f(input("Please enter your age: "),f))
print("You are able to vote in the united states" if int(age)>=18 else "You are not able to vote in the united states",end='')
Wenn Sie maximale Versuche haben möchten, z. B. 3, verwenden Sie den folgenden Code
age=(lambda i,n,f: f(i,n,f))(input("Please enter your age: "),1,lambda i,n,f: i if i.isdigit() else (None if n==3 else f(input("Please enter your age: "),n+1,f)))
print("You are able to vote in the united states" if age and int(age)>=18 else "You are not able to vote in the united states",end='')
Hinweis: Dies verwendet die Rekursion.
Verwenden Sie try-außer, um den Fehler zu behandeln und wiederholen Sie ihn erneut:
while True:
try:
age = int(input("Please enter your age: "))
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.")
except Exception as e:
print("please enter number")