उपयोगकर्ता से इनपुट के लिए पूछना जब तक वे एक वैध प्रतिक्रिया न दें

Apr 25 2014

मैं एक प्रोग्राम लिख रहा हूं जो उपयोगकर्ता से एक इनपुट स्वीकार करता है।

#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इस संदर्भ में एक मान्य , लेकिन निरर्थक है?

जवाब

776 Kevin Apr 25 2014 at 20:31

इसे पूरा करने का सबसे सरल तरीका 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.")

अपने स्वयं के मान्यकरण नियमों को लागू करना

यदि आप उन मानों को अस्वीकार करना चाहते हैं जो पायथन सफलतापूर्वक पार्स कर सकते हैं, तो आप अपना सत्यापन तर्क जोड़ सकते हैं।

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.")

यह सब एक समारोह में Encapsulating

यदि आपको अपने उपयोगकर्ता को बहुत से विभिन्न मूल्यों के लिए पूछने की आवश्यकता है, तो इस कोड को किसी फ़ंक्शन में रखना उपयोगी हो सकता है, इसलिए आपको हर बार इसे फिर से लिखना नहीं होगा।

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विधि से छोटा है , लेकिन यह सॉफ़्टवेयर के विकास के अपने आप को दोहराए जाने के सिद्धांत का उल्लंघन नहीं करता है । इससे आपके सिस्टम में कीड़े होने की संभावना बढ़ जाती है। क्या होगा यदि आप बदलकर 2.7 backport करना चाहते inputकरने के लिए raw_input, लेकिन गलती से केवल पहले बदल inputऊपर? यह SyntaxErrorहोने की प्रतीक्षा है।

रिकर्सन आपका स्टैक उड़ा देगा

यदि आपने केवल पुनरावृत्ति के बारे में सीखा है, get_non_negative_intतो आपको इसका उपयोग करने के लिए लुभाया जा सकता है, ताकि आप लूप का निपटान कर सकें।

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 गलतियाँ नहीं करेगा", लेकिन आप मूर्खों की सरलता को कम आंक रहे हैं!

46 StevenStip Jan 14 2016 at 19:43

आप ऐसा क्यों करेंगे while Trueऔर फिर इस लूप को तोड़ देंगे, जबकि आप अपनी आवश्यकताओं को सिर्फ उस वक्त के बयान में डाल सकते हैं, जब आप चाहते हैं कि एक बार आपकी उम्र कम हो जाए?

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.

यह तब से काम करेगा जब उम्र का कोई मूल्य नहीं होगा जो समझ में नहीं आएगा और कोड आपके "व्यवसाय प्रक्रिया" के तर्क का अनुसरण करता है

26 aaveg Jun 29 2015 at 06:29

हालांकि स्वीकृत उत्तर आश्चर्यजनक है। मैं इस समस्या के लिए एक त्वरित हैक साझा करना चाहूंगा। (यह नकारात्मक उम्र की समस्या का भी ख्याल रखता है।)

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 यह कोड अजगर 3.x के लिए है।

17 Georgy May 10 2019 at 23:47

कार्यात्मक दृष्टिकोण या " मम नो लूप्स! ":

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

यह कैसे काम करता है?

  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
    
  2. 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...
    
  3. हम उन स्ट्रिंग्स का उपयोग करते हैं 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

अन्य सत्यापन नियम:

  1. स्ट्रिंग के तरीके: बेशक आप अन्य स्ट्रिंग विधियों का उपयोग कर सकते हैं जैसे str.isalphaकेवल वर्णानुक्रम स्ट्रिंग str.isupperप्राप्त करने के लिए , या केवल अपरकेस प्राप्त करने के लिए। पूरी सूची के लिए डॉक्स देखें ।

  2. सदस्यता परीक्षण:
    इसे निष्पादित करने के कई अलग-अलग तरीके हैं। उनमें से एक __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
    
  3. संख्या तुलना:
    उपयोगी तुलना विधियां हैं जिनका उपयोग हम यहां कर सकते हैं। उदाहरण के लिए, __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
    

    या, यदि आप डंडर विधियों (डंडर = डबल-अंडरस्कोर) का उपयोग करना पसंद नहीं करते हैं, तो आप हमेशा अपने स्वयं के फ़ंक्शन को परिभाषित कर सकते हैं, या operatorमॉड्यूल से लोगों का उपयोग कर सकते हैं ।

  4. पथ अस्तित्व:
    यहां 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!

प्रीप्रोसेसिंग इनपुट डेटा:

कभी-कभी हम किसी इनपुट को अस्वीकार नहीं करना चाहते हैं अगर उपयोगकर्ता गलती से इसे CAPS में या शुरुआत में या स्ट्रिंग के अंत में एक स्थान के साथ आपूर्ति करता है । इन सरल गलतियों को ध्यान में रखने के लिए हम आवेदन 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

दुर्भाग्य से, अगर किसी को प्रत्येक असफल मामले के लिए एक कस्टम संदेश की आवश्यकता होती है, तो, मुझे डर है, कोई बहुत कार्यात्मक तरीका नहीं है। या, कम से कम, मैं एक नहीं मिल सका।

13 cat Jan 31 2016 at 10:47

इसलिए, मैं हाल ही में इसी तरह के कुछ के साथ गड़बड़ कर रहा था, और मैं निम्नलिखित समाधान के साथ आया, जो इनपुट प्राप्त करने के एक तरीके का उपयोग करता है जो रद्दी को अस्वीकार करता है, इससे पहले कि यह किसी तार्किक तरीके से भी जांचा जाता है।

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!
$ _

ध्यान दें कि इस कार्यान्वयन की प्रकृति यह है कि जैसे ही कोई अंक नहीं पढ़ा जाता है वह स्टड को बंद कर देता है। मैंने एंट्री नहीं की a, लेकिन मुझे नंबर के बाद की जरूरत थी।

आप thismany()इसे केवल एक ही मॉड्यूल में फ़ंक्शन के साथ मर्ज कर सकते हैं , कहने के लिए, तीन अंक।

12 Georgy May 11 2019 at 03:17

क्लिक का उपयोग करना :

क्लिक कमांड-लाइन इंटरफेस के लिए एक पुस्तकालय है और यह उपयोगकर्ता से एक वैध प्रतिक्रिया पूछने के लिए कार्यक्षमता प्रदान करता है।

सरल उदाहरण:

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

ध्यान दें कि यह स्ट्रिंग मान को स्वचालित रूप से फ्लोट में कैसे परिवर्तित करता है।

यदि मान किसी श्रेणी में है, तो जाँच करना:

विभिन्न कस्टम प्रकार प्रदान किए गए हैं। एक विशिष्ट सीमा में एक संख्या प्राप्त करने के लिए हम उपयोग कर सकते हैं 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
3 ojasmohril Jun 23 2016 at 17:34
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."
2 JoãoManuelRodrigues Nov 28 2018 at 21:52

डैनियल क्यू और पैट्रिक आर्टनर के उत्कृष्ट सुझावों के आधार पर, यहां एक और भी सामान्यीकृत समाधान है।

# 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.")
1 PratikAnand Apr 30 2017 at 16:29

इसको आजमाओ:-

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')
1 np8 Oct 30 2020 at 14:12

हाँ, मैं des से 6 साल की देरी से हूँ, लेकिन यह सवाल अधिक जवाब देने योग्य है।

चिंताओ का विभाजन

मैं यूनिक्स दर्शन का एक बड़ा प्रशंसक हूं "एक काम करो और इसे अच्छे से करो" । इस प्रकार की समस्या में, समस्या को विभाजित करने के लिए बेहतर अभ्यास है

  • इनपुट get_inputठीक होने तक इनपुट के साथ पूछें ।
  • validatorसमारोह में मान्य । आप विभिन्न इनपुट प्रश्नों के लिए अलग-अलग सत्यापनकर्ता लिख ​​सकते हैं।

इनपुट के लिए पूछ रहा है

इसे जितना सरल रखा जा सकता है (अजगर 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'

पायथन 3.8+ नोट

पायथन 3.8+ में आप वालरस ऑपरेटर का उपयोग कर सकते हैं

def get_input(prompt, validator, on_validationerror):
    while not validator(value := input(prompt)):
        print(on_validationerror)
    return value 
2Cubed May 31 2016 at 03:47

जबकि एक 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.")
SiddharthSatpathy Dec 18 2018 at 13:17

अच्छा प्रश्न! इसके लिए आप निम्न कोड आज़मा सकते हैं। =)

यह कोड इनपुट के डेटा प्रकार को खोजने के लिए ast.literal_eval () का उपयोग करता है ( )। तब यह निम्नलिखित एल्गोरिथ्म का अनुसरण करता है:age

  1. उपयोगकर्ता से उसके / उसके इनपुट के लिए कहें 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.") 
Ep1c1aN Jul 01 2019 at 16:36

आप हमेशा साधारण इफ-लॉजिक लागू कर सकते हैं और लूप 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

यह एक अनंत लू होगी और आपको अनिश्चित काल तक आयु में प्रवेश करने के लिए कहा जाएगा।

Liju Aug 17 2020 at 15:24

नीचे दिए गए कोड मदद कर सकते हैं।

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='')

नोट: यह पुनरावर्तन का उपयोग करता है।

behnaz.sheikhi Sep 09 2020 at 19:30

त्रुटि को संभालने के लिए और फिर से दोहराने के अलावा कोशिश का उपयोग करें:

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")