사용자가 유효한 응답을 제공 할 때까지 입력 요청
사용자의 입력을 받아들이는 프로그램을 작성 중입니다.
#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
메서드를 while 루프에 넣는 것 입니다. 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
방법 보다 짧기 때문에 매력적으로 보일 수 있지만 소프트웨어 개발 의 Do n't Repeat Yourself 원칙을 위반합니다 . 이렇게하면 시스템에서 버그가 발생할 가능성이 높아집니다. 으로 변경 input
하여 2.7로 백 포트하고 raw_input
싶지만 실수로 input
위 의 첫 번째 만 변경하면 어떻게됩니까? 그것은 SyntaxError
일어나기를 기다리는 것입니다.
재귀는 스택을 날려 버릴 것입니다
재귀에 대해 방금 배웠다 get_non_negative_int
면 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
이것은 대부분의 경우 잘 작동하는 것처럼 보이지만 사용자가 잘못된 데이터를 충분히 입력하면 스크립트가 RuntimeError: maximum recursion depth exceeded
. 당신은 "아무도 연속으로 1000 번의 실수를하지 않을 것"이라고 생각할 수 있지만, 바보의 독창성을 과소 평가하고 있습니다!
while True
당신이 원하는 것은 나이가 생기면 멈추는 것이기 때문에 왜 당신은 왜 a를 하고 나서이 루프에서 벗어나고 당신이 원하는 것은 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 용입니다.
기능적 접근 또는 " 루프가없는 것 같아! ":
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 = 이중 밑줄)를 사용하는 것을 좋아하지 않는 경우 언제든지 자신의 함수를 정의하거나
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을 닫는다는 것입니다. 나는 뒤에 엔터를 치지 a
않았지만 숫자 뒤에 필요했습니다.
thismany()
이를 동일한 모듈 의 함수 와 병합하여 예를 들어 3 자리 만 허용 할 수 있습니다.
클릭 사용 :
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 이상에서는 해마 연산자를 사용할 수 있습니다.
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
이 아닌 경우 사용자에게 나이를 다시 입력하도록 요청합니다 ( 예 : 1 단계로 돌아 가기).float
int
다음은 코드입니다.
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")