dojomaker
dojomaker

Reputation: 269

Check if the input is a string in python

I am trying to check if my input is a string with try-except block. The function runs without an error. However it checks if the input is an integer, not string. How can I inverse this?

def lexicon(word):
    while True:
        try:
            a=str(input(word))
            print("Input is a string. string = ", a)
        except ValueError:
            print("Oops..Input is not supposed to be a number. Try again!")
    return a
b=lexicon("Enter the word you'd like: ")

Upvotes: 0

Views: 8512

Answers (2)

Antimon
Antimon

Reputation: 702

As discussed with user pavel in the comments to his answer, there are two different styles to code for a problem like this: EAFP ("Easier to Ask for Forgiveness than Permission"), meaning that you make your code work on an assumption and take action if it fails; and LBYL ("Look Before You Leap"), in which you first check whether your assumption is true, and then choose the appropriate action to take.

The try/except route is EAFP, since it just executes the code in the try block without bothering to first check whether it would work. If you want to do it in LYBL style, you would explicitly need to ascertain whether the user input is a string representation of a numeric value, and then act accordingly. I'll provide skeletal code for both approaches below. However, note that Python is a little weird compared to other languages in that it seems to have a certain cultural favour for EAFP.

Also, since you are only asking about checking for integers, I will focus on that here. This means that the code will accept floats as valid inputs.

EAFP: try/except

The problem that presumably trips you up is that input always returns a string, so testing if it is a string is nonsensical and will always yield True. However, note that try/except is only an abrigded version of error handling that you can do in Python; the full version is try/except/else/finally. The else block takes effect if no except blocks are executed, and finally is always run at the end. So you could check whether your input is an integer, and make the program raise a failure if that check succeeds. I admit however that this does seem a bit backwards.

try:
    a = int(input())
except ValueError:
    # do whatever
else:
    raise ValueError("Input must not be an integer")

LBYL: if/else

str objects have several methods to test their contents without having to run into errors. For example, .isalpha() checks if all characters are in the alphabet (which returns False however if you include spaces and special characters); isnumeric() checks whether the string is a representation of a number; etc. See a full list here. So depending on what kind of inputs you want to allow, you would need to use one of these methods, or a combination of them, in an if block. The code below essentially does the same thing as the try/except/else version above, using .isdigit() which returns True if all characters in the string are digits (i.e., the same kind of input for which int(a) would succeed).

Note also that I am making use of the new assignment operator := in this code, which is new to Python 3.8. This way, you don't need to explicitly assign the variable a first, however it's a bit harder to catch where the code actually executes an input() function. If you code for backwards compatibility, or don't like the look of this, you'd have to go with the classical a = input() first.

if (a := input()).isdigit():
    raise ValueError("Input must not be an integer")

# do whatever

Upvotes: 3

NotAName
NotAName

Reputation: 4322

If you want specifically to check the value type of the string, you're better off using if/else and isinstance:

if not isinstance(word, str):
    raise TypeError(f"Expecting a string as a value, not {type(word)}.")
else:
    #do something

Upvotes: 2

Related Questions