Python:调用外部函数时出现问题

时间:2015-03-05 04:35:39

标签: python

我是Python的初学者,我遇到了函数问题。我正在制作一个程序,其中我有许多参数供用户选择,我需要允许他们确认或拒绝他们的选择。这是一个代表我的问题的简化代码部分。

我的代码:

def confirm(function):
    while True:
        answer = raw_input('Are you sure? ')
        if answer == 'yes':
            break
        elif answer == 'no':
            return function() # if the user wants to change their name, recall function
        else:
            continue # to reprompt user if the answer is not "yes" or "no"

def your_name():
    while True:
        name = raw_input("What is your name? ")
        if not name:
            continue # to reprompt user if they do not enter anything
        else:
            confirm(your_name)
            print 'Congratulations! You have a name!'
            break
your_name()

运行此程序时,它会以answer收到输入的次数打印祝贺字符串。
我的输出:

What is your name? Bastion
Are you sure? no
What is your name? Artex
Are you sure? no
What is your name? Falcor
Are you sure? yes
Congratulations! You have a name!
Congratulations! You have a name!
Congratulations! You have a name!

我的意图是只打印一次祝贺信息。如何编辑我的功能才能实现这一目标?

我尝试了什么:
我尝试了所有这些,使用我在上面的输出块中使用的完全相同的输入值。 在confirm(function)的部分内写着:

if answer == 'no':
    return function()

我已经尝试将其更改为:

if answer == 'no':
    function()

在输出中,这将要求answer raw_input 3次,在每次输入后发布祝贺消息。如果我以这种方式编写代码:

if answer == 'no':
    print function()

每次在下面单独的一行打印3次打印None的祝贺回复。我正在寻找一种优雅,干净的格式,所以这不行。

6 个答案:

答案 0 :(得分:3)

所以你的问题是你正在创建一种没有意义的递归函数,你不需要再次调用函数,因为你已经在函数内部了。我建议如下:

def confirm():
    while True:
        answer = raw_input('Are you sure? ')
        if answer == 'yes':
            return True
        if answer == 'no':
            return False
        else:
            continue # to reprompt user if the answer is not "yes" or "no"

def your_name():
    while True:
        name = raw_input("What is your name? ")
        if not name:
            continue # to reprompt user if they do not enter anything
        elif confirm():
            print 'Congratulations! You have a name!'
            break
your_name()

答案 1 :(得分:2)

我认为最简洁的方法是将your_name更改为:

def your_name(toplevel=False):
    while True:
        name = raw_input("What is your name? ")
        if not name:
            continue # to reprompt user if they do not enter anything
        else:
            confirm(your_name)
            if toplevel: print 'Congratulations! You have a name!'
            break

以及从顶层到your_name(True)的第一个电话。

还有其他方法,但它们需要全局变量(ecch :-)甚至更脏的技巧来确定是否已从顶层调用该函数;明确告诉它方式更清洁......

答案 2 :(得分:2)

我认为你不必使用所有这些" 递归"打电话,试试这个:

def your_name():
    flag = True
    while flag:
        name = raw_input("What is your name? ")
        if name:
            while True:
                answer = raw_input('Are you sure? ')
                if answer == 'yes':
                    flag = False 
                    break
                elif answer == 'no':
                    break
    print 'Congratulations! You have a name!'

your_name()

使用内部循环询问用户是否确定。使用flag确定主"What is your name? "个问题周期是否结束。

答案 3 :(得分:2)

由于您正在进行的样式递归(对此感到称赞),每次填写答案时,最终都会调用your_name()函数。

我会尝试更像这样的事情:

def confirm():
    answer = ''
    while answer == '':
        answer = raw_input('Are you sure? ')
        if answer == 'yes':
            return True
        elif answer == 'no':
            return False
        else:
            answer = ''

def your_name():
    name = ''
    while name == '':
        name = raw_input("What is your name? ")
    if confirm():
        print 'Congratulations! You have a name!'
    else:
        your_name()

your_name()

答案 4 :(得分:1)

您可以将print 'Congratulations! You have a name!'放在confirmation()函数中而不是your_name()中,这样就可以了:

def confirm(function):
    while True:
        answer = raw_input('Are you sure? ')
        if answer == 'yes':
            print 'Congratulations! You have a name!'
            break
        elif answer == 'no':
            return function() # if the user wants to change their name, recall function
        else:
            continue # to reprompt user if the answer is not "yes" or "no"

def your_name():
    while True:
        name = raw_input("What is your name? ")
        if not name:
            continue 
        else:
            confirm(your_name)
            break
your_name()

BTW,我还在第一个函数中修改了条件语法,这样程序就不会通过两个if语句。

答案 5 :(得分:1)

这个解决方案相对简洁。它循环请求您的姓名,而名称'是一个空字符串。请求确认时,它会将名称重置为空字符串,从而继续循环,除非用户确认“是”'。然后打印用户的姓名以确认其分配。

def your_name():
    name = ''
    while name == '':
        name = raw_input("What is your name? ")
        answer = raw_input('Are you sure (yes or no)? ') if name != '' else 'no'
        name = '' if answer != 'yes' else name
    print 'Congratulations {0}! You have a name!'.format(name)