ขอให้ผู้ใช้ป้อนข้อมูลจนกว่าพวกเขาจะตอบสนองที่ถูกต้อง
ฉันกำลังเขียนโปรแกรมที่ยอมรับข้อมูลจากผู้ใช้
#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.")
โปรแกรมทำงานได้ตามที่คาดหวังตราบเท่าที่ผู้ใช้ป้อนข้อมูลที่มีความหมาย
C:\Python\Projects> canyouvote.py
Please enter your age: 23
You are able to vote in the United States!
แต่จะล้มเหลวหากผู้ใช้ป้อนข้อมูลที่ไม่ถูกต้อง:
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'
แทนที่จะหยุดทำงานฉันต้องการให้โปรแกรมขออินพุตอีกครั้ง แบบนี้:
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!
ฉันจะทำให้โปรแกรมขออินพุตที่ถูกต้องแทนการหยุดทำงานเมื่อป้อนข้อมูลที่ไม่สมเหตุสมผลได้อย่างไร
ฉันจะปฏิเสธค่าเช่น-1
ซึ่งถูกต้องint
แต่ไร้สาระในบริบทนี้ได้อย่างไร
คำตอบ
วิธีที่ง่ายที่สุดในการทำให้สำเร็จคือใส่input
วิธีการในขณะวนซ้ำ ใช้continue
เมื่อคุณได้รับข้อมูลที่ไม่ถูกต้องและbreak
ออกจากวงเมื่อคุณพอใจ
เมื่อข้อมูลที่คุณป้อนอาจเพิ่มข้อยกเว้น
ใช้try
และexcept
ตรวจจับเมื่อผู้ใช้ป้อนข้อมูลที่ไม่สามารถแยกวิเคราะห์ได้
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.")
การใช้กฎการตรวจสอบความถูกต้องของคุณเอง
หากคุณต้องการปฏิเสธค่าที่ Python สามารถแยกวิเคราะห์ได้สำเร็จคุณสามารถเพิ่มตรรกะการตรวจสอบของคุณเองได้
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
การรวมการจัดการข้อยกเว้นและการตรวจสอบความถูกต้องแบบกำหนดเอง
ทั้งสองเทคนิคข้างต้นสามารถรวมเป็นหนึ่งลูปได้
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.")
ห่อหุ้มทั้งหมดในฟังก์ชัน
หากคุณต้องการถามผู้ใช้ของคุณเกี่ยวกับค่าที่แตกต่างกันจำนวนมากการใส่โค้ดนี้ในฟังก์ชันอาจมีประโยชน์ดังนั้นคุณไม่จำเป็นต้องพิมพ์ซ้ำทุกครั้ง
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: ")
วางมันทั้งหมดเข้าด้วยกัน
คุณสามารถขยายแนวคิดนี้เพื่อสร้างฟังก์ชันการป้อนข้อมูลทั่วไปได้:
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
ด้วยการใช้งานเช่น:
age = sanitised_input("Enter your age: ", int, 1, 101)
answer = sanitised_input("Enter your answer: ", str.lower, range_=('a', 'b', 'c', 'd'))
ข้อผิดพลาดทั่วไปและเหตุใดคุณจึงควรหลีกเลี่ยง
การใช้input
งบซ้ำซ้อน
วิธีนี้ใช้ได้ผล แต่โดยทั่วไปถือว่าเป็นรูปแบบที่ไม่ดี:
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): ")
อาจดูน่าสนใจในตอนแรกเนื่องจากสั้นกว่าwhile True
วิธีการนี้ แต่เป็นการละเมิดหลักการพัฒนาซอฟต์แวร์Don't Repeat Yourself ซึ่งจะเพิ่มโอกาสที่จะเกิดจุดบกพร่องในระบบของคุณ จะเกิดอะไรขึ้นถ้าคุณต้องการย้อนกลับเป็น 2.7 โดยเปลี่ยนinput
เป็นraw_input
แต่บังเอิญเปลี่ยนเฉพาะรายการแรกinput
ข้างต้น? มันเป็นSyntaxError
เพียงการรอคอยที่จะเกิดขึ้น
การเรียกซ้ำจะระเบิดกองของคุณ
หากคุณเพิ่งเรียนรู้เกี่ยวกับการเรียกซ้ำคุณอาจถูกล่อลวงให้ใช้มันget_non_negative_int
เพื่อให้คุณสามารถกำจัด while loop ได้
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
ดูเหมือนว่าจะทำงานได้ดีเกือบตลอดเวลา แต่ถ้าผู้ใช้ป้อนข้อมูลที่ไม่ถูกต้องหลายครั้งมากพอสคริปต์จะจบลงด้วยไฟล์RuntimeError: maximum recursion depth exceeded
. คุณอาจคิดว่า "ไม่มีคนโง่คนใดที่จะทำผิดพลาด 1,000 ครั้งติดต่อกัน" แต่คุณประเมินความฉลาดของคนโง่ต่ำเกินไป!
ทำไมคุณถึงทำ a while True
แล้วแยกออกจากลูปนี้ในขณะที่คุณสามารถใส่ความต้องการของคุณในคำสั่ง while ได้เนื่องจากสิ่งที่คุณต้องการคือหยุดเมื่อคุณมีอายุ
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.")
ซึ่งจะส่งผลดังต่อไปนี้:
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.
สิ่งนี้จะใช้ได้ผลตั้งแต่อายุจะไม่มีค่าที่จะไม่สมเหตุสมผลและรหัสจะเป็นไปตามตรรกะของ "กระบวนการทางธุรกิจ" ของคุณ
แม้ว่าคำตอบที่ได้รับการยอมรับจะน่าทึ่ง ฉันต้องการแบ่งปันการแฮ็กอย่างรวดเร็วสำหรับปัญหานี้ (สิ่งนี้ช่วยดูแลปัญหาอายุเชิงลบด้วย)
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: ")))
ปล. รหัสนี้ใช้สำหรับ python 3.x.
แนวทางการทำงานหรือ " look mum 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
หรือหากคุณต้องการให้ข้อความ "อินพุตไม่ถูกต้อง" แยกออกจากข้อความแจ้งการป้อนข้อมูลเช่นเดียวกับคำตอบอื่น ๆ :
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: "))
itertools.chain
และitertools.repeat
จะสร้างตัววนซ้ำซึ่งจะให้สตริง"Enter a number: "
ครั้งเดียวและ"Not a number! Try again: "
จำนวนครั้งไม่สิ้นสุด: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)
- ที่นี่map
จะใช้prompts
สตริงทั้งหมดจากขั้นตอนก่อนหน้ากับinput
ฟังก์ชัน เช่น: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
และstr.isdigit
เพื่อกรองสตริงที่มีเพียงตัวเลข: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...
next
และเพื่อให้ได้เพียงตัวเลขเพียงครั้งแรกที่ใช้สตริงเรา
กฎการตรวจสอบอื่น ๆ :
วิธีการสตริง:แน่นอนคุณสามารถใช้วิธีการสตริงอื่น ๆ เช่น
str.isalpha
รับเฉพาะสตริงตัวอักษรหรือstr.isupper
รับเฉพาะตัวพิมพ์ใหญ่ ดูเอกสารสำหรับรายการทั้งหมดการทดสอบการเป็นสมาชิก:
มีหลายวิธีในการดำเนินการ หนึ่งในนั้นคือการใช้__contains__
วิธีการ: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
การเปรียบเทียบตัวเลข:
มีวิธีการเปรียบเทียบที่เป็นประโยชน์ซึ่งเราสามารถใช้ได้ที่นี่ ตัวอย่างเช่นสำหรับ__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
หรือถ้าคุณไม่ชอบใช้วิธี dunder (dunder = double-underscore) คุณสามารถกำหนดฟังก์ชันของคุณเองหรือใช้ฟังก์ชันจาก
operator
โมดูลก็ได้การมีอยู่ของเส้นทาง: ที่
นี่คุณสามารถใช้pathlib
ไลบรารีและPath.exists
วิธีการ: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
การ จำกัด จำนวนครั้ง:
หากคุณไม่ต้องการทรมานผู้ใช้ด้วยการถามเขาเป็นจำนวนครั้งไม่ จำกัด คุณสามารถระบุขีด จำกัด ในการโทรitertools.repeat
ได้ สามารถใช้ร่วมกับการระบุค่าเริ่มต้นให้กับnext
ฟังก์ชัน:
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!
การประมวลผลข้อมูลอินพุตล่วงหน้า:
บางครั้งเราไม่ต้องการปฏิเสธอินพุตหากผู้ใช้ป้อนข้อมูลนั้นโดยไม่ได้ตั้งใจเป็นตัวพิมพ์หรือมีช่องว่างในตอนต้นหรือตอนท้ายของสตริง ในการพิจารณาข้อผิดพลาดง่ายๆเหล่านี้เราสามารถประมวลผลข้อมูลอินพุตล่วงหน้าได้โดยใช้str.lower
และstr.strip
วิธีการ ตัวอย่างเช่นในกรณีของการเป็นสมาชิกการทดสอบรหัสจะมีลักษณะดังนี้:
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
ในกรณีที่เมื่อคุณมีฟังก์ชั่นมากมายที่จะใช้สำหรับการประมวลผลเบื้องต้นก็อาจจะง่ายต่อการใช้ฟังก์ชั่นการแสดงองค์ประกอบของฟังก์ชั่น ตัวอย่างเช่นใช้จากที่นี่ :
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
การรวมกฎการตรวจสอบความถูกต้อง:
ยกตัวอย่างง่ายๆเช่นเมื่อโปรแกรมถามอายุระหว่าง 1 ถึง 120 ก็สามารถเพิ่มได้อีก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)
แต่ในกรณีที่มีกฎระเบียบมากจะดีกว่าที่จะใช้ฟังก์ชั่นการดำเนินการร่วมตรรกะ ในตัวอย่างต่อไปนี้ฉันจะใช้อันที่พร้อมจากที่นี่ :
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
แต่ถ้ามีคนต้องการที่ข้อความที่กำหนดเองสำหรับแต่ละกรณีล้มเหลวแล้วฉันกลัวไม่มีสวยวิธีการทำงาน หรืออย่างน้อยก็หาไม่เจอ
ดังนั้นฉันจึงยุ่งกับสิ่งที่คล้ายกับสิ่งนี้เมื่อไม่นานมานี้และฉันได้หาวิธีแก้ปัญหาต่อไปนี้ซึ่งใช้วิธีการรับข้อมูลที่ปฏิเสธขยะก่อนที่จะตรวจสอบด้วยวิธีเชิงตรรกะ
read_single_keypress()
เอื้อเฟื้อ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()
คุณสามารถค้นหาโมดูลที่สมบูรณ์ที่นี่
ตัวอย่าง:
$ ./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!
$ _
โปรดทราบว่าลักษณะของการใช้งานนี้จะปิด stdin ทันทีที่อ่านสิ่งที่ไม่ใช่ตัวเลข ฉันไม่ได้กด Enter a
แต่ฉันต้องการตามหลังตัวเลข
คุณสามารถรวมสิ่งนี้เข้ากับthismany()
ฟังก์ชันในโมดูลเดียวกันเพื่ออนุญาตให้พูดสามหลักเท่านั้น
ใช้คลิก :
Clickเป็นไลบรารีสำหรับอินเตอร์เฟสบรรทัดคำสั่งและมีฟังก์ชันสำหรับการถามการตอบกลับที่ถูกต้องจากผู้ใช้
ตัวอย่างง่ายๆ:
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
สังเกตว่ามันแปลงค่าสตริงเป็น float โดยอัตโนมัติได้อย่างไร
ตรวจสอบว่าค่าอยู่ในช่วงหรือไม่:
มีประเภทกำหนดเองที่แตกต่างกันให้ หากต้องการรับตัวเลขในช่วงที่กำหนดเราสามารถใช้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
นอกจากนี้เรายังสามารถระบุขีด จำกัด เพียงข้อเดียวmin
หรือ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
การทดสอบการเป็นสมาชิก:
ใช้click.Choice
ประเภท โดยค่าเริ่มต้นการตรวจสอบนี้คำนึงถึงตัวพิมพ์เล็กและใหญ่
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
การทำงานกับเส้นทางและไฟล์:
การใช้click.Path
ประเภทเราสามารถตรวจสอบเส้นทางที่มีอยู่และแก้ไขได้:
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
การอ่านและเขียนไฟล์สามารถทำได้โดย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
ค่าเริ่มต้น:
ในกรณีนี้เพียงแค่กดEnter(หรือปุ่มใดก็ตามที่คุณใช้) โดยไม่ต้องป้อนค่าจะทำให้คุณได้ค่าเริ่มต้น:
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."
จากคำแนะนำที่ยอดเยี่ยมของ Daniel Q และ Patrick Artner นี่เป็นวิธีแก้ปัญหาที่ครอบคลุมยิ่งขึ้น
# 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)
ฉันเลือกใช้ข้อความที่ชัดเจนif
และraise
ข้อความแทนassert
เนื่องจากอาจปิดการตรวจสอบการยืนยันในขณะที่การตรวจสอบความถูกต้องควรเปิดใช้งานอยู่เสมอเพื่อให้มีประสิทธิภาพ
อาจใช้เพื่อรับอินพุตประเภทต่างๆโดยมีเงื่อนไขการตรวจสอบความถูกต้องที่แตกต่างกัน ตัวอย่างเช่น:
# 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!"})
หรือเพื่อตอบคำถามเดิม:
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.")
ลองอันนี้:-
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')
ใช่ฉันมาช้าไป 6 ปีแล้วแต่คำถามนี้สมควรได้รับคำตอบที่เป็นปัจจุบันมากกว่านี้
การแยกความกังวล
ฉันเป็นแฟนตัวยงของยูนิกซ์ปรัชญา"ทำสิ่งหนึ่งและทำมันได้ดี" ในปัญหาประเภทนี้การแยกปัญหาเป็นวิธีที่ดีกว่า
- ถามอินพุต
get_input
จนกว่าอินพุตจะโอเค - ตรวจสอบใน
validator
ฟังก์ชัน คุณสามารถเขียนตัวตรวจสอบความถูกต้องที่แตกต่างกันสำหรับการสืบค้นข้อมูลเข้า
ขอข้อมูลเข้า
สามารถเก็บไว้ได้ง่ายๆเหมือน (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'
Python 3.8+ หมายเหตุ
ใน Python 3.8+ คุณสามารถใช้ตัวดำเนินการ walrus
def get_input(prompt, validator, on_validationerror):
while not validator(value := input(prompt)):
print(on_validationerror)
return value
ในขณะที่try
/ บล็อกจะทำงานเป็นวิธีที่เร็วและทำความสะอาดเพื่อทํางานนี้จะมีการใช้งานexcept
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.")
คำถามที่ดี! คุณสามารถลองใช้รหัสต่อไปนี้สำหรับสิ่งนี้ =)
รหัสนี้ใช้ast.literal_eval ()เพื่อค้นหาประเภทข้อมูลของอินพุต ( age
) จากนั้นเป็นไปตามอัลกอริทึมต่อไปนี้:
age
ขอให้ผู้ใช้ต้องใส่เธอ / เขา1.1. ถ้า
age
เป็นfloat
หรือint
ประเภทข้อมูล:
ตรวจสอบว่า
age>=18
. หากage>=18
พิมพ์เอาต์พุตที่เหมาะสมและออกตรวจสอบว่า
0<age<18
. หาก0<age<18
พิมพ์เอาต์พุตที่เหมาะสมและออกหาก
age<=0
ขอให้ผู้ใช้ป้อนตัวเลขอายุที่ถูกต้องอีกครั้ง ( เช่นกลับไปที่ขั้นตอนที่ 1)1.2. หาก
age
ไม่ใช่float
หรือint
ประเภทข้อมูลให้ขอให้ผู้ใช้ป้อนอายุอีกครั้ง ( เช่นกลับไปที่ขั้นตอนที่ 1)
นี่คือรหัส
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.")
คุณสามารถใช้ตรรกะ if-else อย่างง่ายและเพิ่มif
ตรรกะอีกอย่างหนึ่งให้กับโค้ดของคุณพร้อมกับfor
ลูป
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
นี่จะเป็นลูที่ไม่มีที่สิ้นสุดและคุณจะถูกขอให้ป้อนอายุไปเรื่อย ๆ
โค้ดด้านล่างอาจช่วยได้
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='')
หากคุณต้องการพยายามสูงสุดให้พูด 3 ใช้โค้ดด้านล่าง
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='')
หมายเหตุ: ใช้การเรียกซ้ำ
ใช้ try-except เพื่อจัดการข้อผิดพลาดและทำซ้ำอีกครั้ง:
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")