Tôi đang viết một chương trình chấp nhận đầu vào từ người dùng.
#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.")
Chương trình hoạt động như mong đợi miễn là người dùng nhập dữ liệu có ý nghĩa.
C:\Python\Projects> canyouvote.py
Please enter your age: 23
You are able to vote in the United States!
Nhưng nó không thành công nếu người dùng nhập dữ liệu không hợp lệ:
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'
Thay vì gặp sự cố, tôi muốn chương trình yêu cầu nhập lại. Như thế này:
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!
Làm cách nào tôi có thể yêu cầu chương trình nhập các đầu vào hợp lệ thay vì bị treo khi nhập dữ liệu không hợp lý?
Làm cách nào để tôi có thể từ chối các giá trị như giá trị -1
hợp lệ int
nhưng vô nghĩa trong bối cảnh này?
Cách đơn giản nhất để thực hiện điều này là đặt input
phương thức trong một vòng lặp while. Sử dụng continue
khi bạn nhận được thông tin đầu vào không tốt và break
ra khỏi vòng lặp khi bạn hài lòng.
Sử dụng try
vàexcept
để phát hiện khi người dùng nhập dữ liệu không thể phân tích cú pháp.
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.")
Nếu bạn muốn từ chối các giá trị mà Python có thể phân tích cú pháp thành công, bạn có thể thêm logic xác thực của riêng mình.
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
Cả hai kỹ thuật trên có thể được kết hợp thành một vòng lặp.
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.")
Nếu bạn cần yêu cầu người dùng của mình cung cấp nhiều giá trị khác nhau, có thể hữu ích khi đặt mã này vào một hàm để bạn không phải nhập lại mã mỗi lần.
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: ")
Bạn có thể mở rộng ý tưởng này để tạo một hàm đầu vào rất chung chung:
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
Với cách sử dụng như:
age = sanitised_input("Enter your age: ", int, 1, 101)
answer = sanitised_input("Enter your answer: ", str.lower, range_=('a', 'b', 'c', 'd'))
input
câu lệnh dự phòngPhương pháp này hoạt động nhưng thường được coi là kiểu kém:
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): ")
Ban đầu, nó có vẻ hấp dẫn vì nó ngắn hơn while True
phương pháp, nhưng nó vi phạm nguyên tắc Không lặp lại bản thân trong phát triển phần mềm. Điều này làm tăng khả năng xuất hiện lỗi trong hệ thống của bạn. Điều gì sẽ xảy ra nếu bạn muốn backport thành 2.7 bằng cách thay đổi input
thành raw_input
, nhưng vô tình chỉ thay đổi input
ở trên? Nó SyntaxError
chỉ đang chờ đợi để xảy ra.
Nếu bạn vừa mới học về đệ quy, bạn có thể muốn sử dụng nó get_non_negative_int
để có thể loại bỏ vòng lặp while.
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
Điều này dường như hoạt động tốt trong hầu hết thời gian, nhưng nếu người dùng nhập dữ liệu không hợp lệ đủ lần, tập lệnh sẽ kết thúc bằng a RuntimeError: maximum recursion depth exceeded
. Bạn có thể nghĩ rằng "không có kẻ ngốc nào phạm 1000 lỗi liên tiếp", nhưng bạn đang đánh giá thấp sự khéo léo của những kẻ ngu ngốc!
Tại sao bạn lại thực hiện một while True
và sau đó thoát ra khỏi vòng lặp này trong khi bạn cũng có thể chỉ cần đưa các yêu cầu của mình vào câu lệnh while vì tất cả những gì bạn muốn là dừng lại khi đã đủ tuổi?
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.")
Điều này sẽ dẫn đến những điều sau:
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.
điều này sẽ hoạt động vì tuổi tác sẽ không bao giờ có giá trị không có ý nghĩa và mã tuân theo logic của "quy trình kinh doanh" của bạn
Mặc dù câu trả lời được chấp nhận là tuyệt vời. Tôi cũng muốn chia sẻ một cách hack nhanh chóng cho vấn đề này. (Điều này cũng giải quyết vấn đề tuổi tác tiêu cực.)
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 Mã này dành cho python 3.x.
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
hoặc nếu bạn muốn tách thông báo "đầu vào không hợp lệ" khỏi lời nhắc nhập như trong các câu trả lời khác:
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
prompts = chain(["Enter a number: "], repeat("Not a number! Try again: "))
Sự kết hợp này itertools.chain
và itertools.repeat
sẽ tạo ra một trình lặp sẽ mang lại chuỗi "Enter a number: "
một lần và "Not a number! Try again: "
số lần vô hạn:
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)
- ở đây map
sẽ áp dụng tất cả các prompts
chuỗi từ bước trước cho input
hàm. Ví dụ:
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...
filter
và str.isdigit
để lọc ra những chuỗi chỉ chứa các chữ số:
only_digits = filter(str.isdigit, replies)
for reply in only_digits:
print(reply)
Enter 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...
Và để chỉ lấy chuỗi chỉ có chữ số đầu tiên, chúng tôi sử dụng next
.Phương thức chuỗi: Tất nhiên bạn có thể sử dụng các phương thức chuỗi khác như str.isalpha
chỉ lấy chuỗi chữ cái hoặc str.isupper
chỉ lấy chữ hoa. Xem tài liệu để biết danh sách đầy đủ.
Kiểm tra tư cách thành viên:
Có một số cách khác nhau để thực hiện. Một trong số đó là sử dụng __contains__
phương pháp:
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
So sánh số:
Có những phương pháp so sánh hữu ích mà chúng ta có thể sử dụng ở đây. Ví dụ, cho __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
Hoặc, nếu bạn không thích sử dụng các phương thức dunder (dunder = double-underscore), bạn luôn có thể xác định hàm của riêng mình hoặc sử dụng các hàm từ operator
mô-đun.
Sự tồn tại của đường dẫn:
Ở đây người ta có thể sử dụng pathlib
thư viện và Path.exists
phương thức của nó :
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
Nếu bạn không muốn tra tấn người dùng bằng cách hỏi anh ta điều gì đó vô số lần, bạn có thể chỉ định giới hạn trong một lệnh gọi itertools.repeat
. Điều này có thể được kết hợp với việc cung cấp giá trị mặc định cho next
hàm:
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!
Đôi khi chúng tôi không muốn từ chối một đầu vào nếu người dùng vô tình cung cấp nó IN HOA hoặc có khoảng trắng ở đầu hoặc cuối chuỗi. Để tính đến những sai lầm đơn giản này, chúng ta có thể xử lý trước dữ liệu đầu vào bằng cách áp dụng str.lower
và str.strip
các phương pháp. Ví dụ: đối với trường hợp kiểm tra tư cách thành viên, mã sẽ như thế này:
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
Trong trường hợp bạn có nhiều hàm cần sử dụng để tiền xử lý, thì việc sử dụng một hàm thực hiện một thành phần hàm có thể dễ dàng hơn . Ví dụ: sử dụng một từ đây :
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
Đối với một trường hợp đơn giản, chẳng hạn, khi chương trình yêu cầu độ tuổi từ 1 đến 120, người ta có thể thêm một người khác 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)
Nhưng trong trường hợp có nhiều quy tắc, tốt hơn nên triển khai một hàm thực hiện kết hợp logic . Trong ví dụ sau, tôi sẽ sử dụng một cái sẵn sàng từ đây :
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
Thật không may, nếu ai đó cần có một thông báo tùy chỉnh cho từng trường hợp thất bại, sau đó, tôi sợ, không có khá cách chức năng. Hoặc, ít nhất, tôi không thể tìm thấy một.
Vì vậy, gần đây tôi đã làm lộn xộn với một thứ tương tự như thế này, và tôi đã đưa ra giải pháp sau, sử dụng một cách nhận đầu vào để loại bỏ rác, trước khi nó được kiểm tra theo bất kỳ cách hợp lý nào.
read_single_keypress()
lịch sự 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()
Bạn có thể tìm thấy mô-đun hoàn chỉnh ở đây .
Thí dụ:
$ ./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!
$ _
Lưu ý rằng bản chất của việc triển khai này là nó đóng stdin ngay sau khi một thứ gì đó không phải là chữ số được đọc. Tôi không nhấn enter sau a
, nhưng tôi cần nhấn sau các con số.
Bạn có thể hợp nhất hàm này với thismany()
hàm trong cùng một mô-đun để chỉ cho phép, chẳng hạn, ba chữ số.
Click là một thư viện cho các giao diện dòng lệnh và nó cung cấp chức năng để yêu cầu phản hồi hợp lệ từ người dùng.
Ví dụ đơn giản:
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
Lưu ý cách nó tự động chuyển đổi giá trị chuỗi thành một số nổi.
Có các loại tùy chỉnh khác nhau được cung cấp. Để nhận một số trong một phạm vi cụ thể, chúng ta có thể sử dụng 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
Chúng tôi cũng có thể chỉ định một trong các giới hạn min
hoặc 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
Đang sử dụng click.Choice
loại. Theo mặc định, kiểm tra này phân biệt chữ hoa chữ thường.
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
Sử dụng một click.Path
loại, chúng tôi có thể kiểm tra các đường dẫn hiện có và cũng giải quyết chúng:
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
Việc đọc và ghi tệp có thể được thực hiện bằng cách 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!
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
Trong trường hợp này, chỉ cần nhấn Enter(hoặc bất kỳ phím nào bạn sử dụng) mà không nhập giá trị, sẽ cung cấp cho bạn giá trị mặc định:
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."
Dựa trên các đề xuất tuyệt vời của Daniel Q và Patrick Artner, đây là một giải pháp tổng quát hơn.
# 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)
Tôi đã chọn rõ ràng if
và raise
tuyên bố thay vì một assert
, vì kiểm tra xác nhận có thể bị tắt, trong khi xác thực phải luôn được bật để cung cấp tính mạnh mẽ.
Điều này có thể được sử dụng để nhận các loại đầu vào khác nhau, với các điều kiện xác nhận khác nhau. Ví dụ:
# 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!"})
Hoặc, để trả lời câu hỏi ban đầu:
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.")
Hãy thử cái này: -
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('[[email protected]#$%^&*()_+{}":/\']+$').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')
Vâng, tôi đã trễ 6 năm kể từ ngày 🎉 nhưng câu hỏi này xứng đáng có câu trả lời cập nhật hơn.
Tôi là một fan hâm mộ lớn của triết lý Unix "Làm một việc và làm tốt" . Trong loại vấn đề này, cách tốt hơn là chia vấn đề thành
get_input
cho đến khi đầu vào là ok.validator
chức năng. Bạn có thể viết các trình xác thực khác nhau cho các truy vấn đầu vào khác nhau.Nó có thể được giữ đơn giản như (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)
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'
Trong Python 3.8+, bạn có thể sử dụng toán tử hải mã
def get_input(prompt, validator, on_validationerror):
while not validator(value := input(prompt)):
print(on_validationerror)
return value
Mặc dù a try
/ except
block sẽ hoạt động, nhưng cách nhanh hơn và rõ ràng hơn để hoàn thành tác vụ này là sử dụng 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.")
Câu hỏi hay! Bạn có thể thử mã sau cho điều này. =)
Mã này sử dụng ast.literal_eval () để tìm kiểu dữ liệu của đầu vào ( age
). Sau đó, nó tuân theo thuật toán sau:
Yêu cầu người dùng nhập cô ấy / anh ấy
age
.1.1. Nếu
age
làfloat
hoặcint
kiểu dữ liệu:
Kiểm tra xem
age>=18
. Nếuage>=18
, in đầu ra thích hợp và thoát.Kiểm tra xem
0<age<18
. Nếu0<age<18
, in đầu ra thích hợp và thoát.Nếu
age<=0
, hãy yêu cầu người dùng nhập lại một số hợp lệ cho độ tuổi, ( tức là quay lại bước 1)1.2. Nếu
age
không phảifloat
hoặcint
kiểu dữ liệu, hãy yêu cầu người dùng nhập lại tuổi của cô ấy / anh ấy ( tức là quay lại bước 1)
Đây là mã.
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.")
Bạn luôn có thể áp dụng logic if-else đơn giản và thêm một if
logic nữa vào mã của mình cùng với một for
vòng lặp.
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
Đây sẽ là khoảng thời gian vô hạn và bạn sẽ được yêu cầu nhập độ tuổi vô thời hạn.
Mã dưới đây có thể hữu ích.
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='')
Nếu bạn muốn có số lần thử tối đa, hãy nói 3, sử dụng mã bên dưới
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='')
Lưu ý: Điều này sử dụng đệ quy.
Sử dụng thử ngoại trừ để xử lý lỗi và lặp lại lỗi:
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")
Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.
Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?
Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.
Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.
The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!
Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.
Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?
Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.
Edward Norton đã muốn đưa cuốn tiểu thuyết Motherless Brooklyn của Jonathan Lethem's Joycean 1999 lên màn ảnh kể từ khi nó được xuất bản. Bây giờ, 20 năm sau, một đoạn giới thiệu đã xuất hiện cho câu chuyện sôi nổi, đưa câu chuyện của Lethem trở lại những năm 1950 với rất nhiều gương mặt quen thuộc.
Có thích thú khi sử dụng Thẻ Apple mới của bạn không? Trước khi bạn bắt đầu chi tiêu, có một nhiệm vụ bổ sung cần xem xét: chọn không tham gia trọng tài ràng buộc. Bạn sẽ phát hiện ra các điều khoản trọng tài ràng buộc trong nhiều thỏa thuận tài chính vì nó giúp ngăn các ngân hàng và đối tác kinh doanh của họ không phải ra tòa.
Điểm số tại vòng chung kết Fortnite World Cup Solo hôm nay là rất lớn, với người chiến thắng Bugha ghi được nhiều hơn 26 điểm so với người về thứ hai là Psalm. Nhưng không phải ai cũng có thể giành chiến thắng: Bốn cầu thủ ra về với 0 điểm, nhưng — ít nhất là trên Twitter — họ là những người thể thao tốt về điều đó.
Huấn luyện viên trưởng của bộ môn thể dục dụng cụ UCLA Valorie Kondos-Field theo dõi Katelyn Ohashi thi đấu thăng bằng trong trận gặp Stanford tại Pauley Pavilion vào ngày 10 tháng 3 năm 2019 ở Los Angeles, California. Vụ bê bối gian lận tuyển sinh đại học tiết lộ các chi tiết của một quá trình chính thức hóa để đưa những đứa trẻ thất bại của các gia đình giàu có và nổi tiếng vào các trường đại học đáng tin cậy và danh tiếng, sử dụng một "cửa phụ" đắt tiền cho các bậc cha mẹ mà sự giàu có của họ khiến họ không có cơ hội. chỉ cần tài trợ cho một cánh mới trong khuôn viên trường.
Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!
Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!
Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không
Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"
Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.
Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.
Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.
Bài đăng này khám phá tầm nhìn về đám mây phi tập trung của nhóm DFINITY và cách nó liên quan đến các nhà cung cấp blockchain truyền thống và đám mây hiện có như Amazon Web Services. Các minh chứng về công nghệ DFINITY được áp dụng bởi một mạng lưới quy mô lớn sẽ được thực hiện vào mùa thu năm 2017, sau đó sẽ được gây quỹ Chính cho quỹ hỗ trợ phi lợi nhuận, với mạng “đám mây mở” dự kiến sẽ ra mắt vào đầu mùa hè năm 2018 .