检查用户输入是否有效后,Python函数返回None

时间:2017-06-20 07:35:02

标签: python python-3.x

我刚刚开始学习编程,并且一直在玩Python。我写了一个小程序,根据用户输入(骰子上的边数和骰子数)掷骰子。这是代码:

from random import randrange


def number_of_sides():
    n = input("How many sides? ")  # Get input from the user
    if n.isdigit():  # Check if the input is a digit
        n = int(n)  # If it is, turn it into an integer
        return n  # And return the value of n
    else:
        print("Invalid input. ")  # If test returns false, rerun function
        number_of_sides()


def number_of_dice():
    m = input("How many dice? ")  # Get input from the user
    if m.isdigit():  # Check if the input is a digit
        m = int(m)  # If it is, turn it into an integer
        return m  # And return the value of m
    else:
        print("Invalid input. ")  # If test returns false, rerun function
        number_of_dice()


def play_again() -> object:  # Checks if user answered yes or no, then reruns everything or exits with exit code 0
    answ = input("Do you want to play again?(yes/no) ")
    if answ == "yes":
        dice_roll()
    elif answ == "no":
        print("Ok then")
        return True
    else:
        print("Input invalid, trying again")
        play_again()


def dice_roll():  # sides - for number of sides, dice - for number of dice.
    sides = number_of_sides()  # Whatever number the function returns
    dice = number_of_dice()  # Whatever number the function returns
    results = [] # empty list, here is where results will be appended
    for i in range(1, dice + 1):  # That returns values for each dice specified in the dice variable
        throw = randrange(1, sides + 1)
        results.append(throw)
        results_str = " | ".join(str(i) for i in results)  # Turn the list into string, separate results with a pipe
    print(results_str)  # Print the results of throws
    play_again()  # Ask the user to play again


dice_roll()

当我提供有效输入(所有数字如6和6为侧面和骰子)时,一切正常,但是当我尝试首先提供无效输入时,它会崩溃。由于某种原因,number_of_sides()和number_of_dice()函数在首次输入无效输入时返回None,然后在dice_roll()函数中的for循环中崩溃:

How many sides? a
Invalid input. 
How many sides? 6
How many dice? 6
Traceback (most recent call last):
  File "<directory>/dice_roll.py", line 48, in <module>
    dice_roll()
  File "<directory>/dice_roll.py", line 41, in dice_roll
    throw = randrange(1, sides + 1)
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

Process finished with exit code 1

我分别测试了这些功能,它们似乎工作正常。这个片段:

def number_of_sides():
    n = input("How many sides? ")
    if n.isdigit():
        n = int(n)
        print(n, ", ", type(n))
        return n
    else:
        print(n, ", ", type(n))
        number_of_sides()

如果你提供一个字符串,则返回str;如果你提供数字,则返回int。我想知道可能导致这种奇怪行为的原因。

3 个答案:

答案 0 :(得分:2)

问题在于您以递归方式调用number_of_dice ,但忽略了其结果。您应该使用以下命令替换递归调用:

return number_of_dice()

甚至更好,通过使用简单的while循环来消除递归:

def number_of_dice():
    while True:
        m = input("How many dice? ")  # Get input from the user
        if m.isdigit():  # Check if the input is a digit
            m = int(m)  # If it is, turn it into an integer
            return m  # And return the value of m
        else:
            print("Invalid input. ")  

显然,同样适用于其他功能。

答案 1 :(得分:1)

我似乎函数number_of_sides()和number_of_dice()仅在第一个输入正确时才返回有效值,否则它们自行循环但新输入不会返回到main函数。 在这种情况下,我认为递归并不好。

您可以像这样转换number_of_dices:

def number_of_sides():
    nb_sides = input("How many sides? ")

    while (nb_sides.isdigit())==False:
        print("Invalid input. ")
        nb_sides=input("How many sides? ")

    return int(nb_sides)

有关您的信息,您还可以使用:

import pdb
pdb.set_trace()

暂停特定行中的代码

答案 2 :(得分:0)

&#34;返回&#34;您的失败案例中的陈述在2个陈述中缺失

from random import randrange


def number_of_sides():
    n = input("How many sides? ")  # Get input from the user
    if n.isdigit():  # Check if the input is a digit
        n = int(n)  # If it is, turn it into an integer
        return n  # And return the value of n
    else:
        print("Invalid input. ")  # If test returns false, rerun function
        return number_of_sides()


def number_of_dice():
    m = input("How many dice? ")  # Get input from the user
    if m.isdigit():  # Check if the input is a digit
        m = int(m)  # If it is, turn it into an integer
        return m  # And return the value of m
    else:
        print("Invalid input. ")  # If test returns false, rerun function
        return number_of_dice()


def play_again() -> object:  # Checks if user answered yes or no, then reruns everything or exits with exit code 0
    answ = input("Do you want to play again?(yes/no) ")
    if answ == "yes":
        dice_roll()
    elif answ == "no":
        print("Ok then")
        return True
    else:
        print("Input invalid, trying again")
        play_again()


def dice_roll():  # sides - for number of sides, dice - for number of dice.
    sides = number_of_sides()  # Whatever number the function returns
    dice = number_of_dice()  # Whatever number the function returns
    results = [] # empty list, here is where results will be appended
    for i in range(1, dice + 1):  # That returns values for each dice specified in the dice variable
        throw = randrange(1, sides + 1)
        results.append(throw)
        results_str = " | ".join(str(i) for i in results)  # Turn the list into string, separate results with a pipe
    print(results_str)  # Print the results of throws
    play_again()  # Ask the user to play again


dice_roll()