嵌套函数是Pythonic吗?

时间:2016-11-22 17:40:18

标签: python python-3.x raspberry-pi nested-function

我在R.Pi上学习Python,而且我遇到了一个小问题。在我看来,以下代码将留下" inputchecker"函数在内存中打开,然后返回到" getinput"功能。

这是不好的代码吗?它应该以非常不同的方式完成吗?

def getinput(i):    
    if i == 1:
        first = input("Would you like A or B? ")
        inputchecker(1, first)
    elif i == 2:
        second = input("Would you like C or D? ")
        inputchecker(2, second)

def inputchecker(n, userinput):    
    def _tryagain_(n):
        usage(n)
        getinput(n)        
    if n == 1:
        if userinput in ("A", "B"):
            print("You chose wisely.")
            getinput(2)
        else:
            _tryagain_(n)
    elif n == 2:
        if userinput in ("C", "D"):
            print("You chose wisely.")
        else:
            _tryagain_(n)

def usage(u):
    if u == 1:
        print("Usage: Just A or B please.") 
    if u == 2:
        print("Usage: Just C or D please.") 


getinput(1)

3 个答案:

答案 0 :(得分:2)

不,嵌套函数中的名称getinput不会创建引用。每次调用_tryagain_时都会查找它,因为它是全局的。这并不重要,因为当Python退出时整个模块被清除,这里没有真正的内存泄漏机会。

但是,您正在使用递归来询问用户输入,并且您的代码很难遵循。请改用简单的循环,请参阅Asking the user for input until they give a valid response

答案 1 :(得分:1)

两个函数无限地相互调用并不是最好的控制流程。使用while循环

会更好
def getinput(i):
    while i:    
        if i == 1:
            first = input("Would you like A or B? ")
            i = inputchecker(1, first)
        elif i == 2:
            second = input("Would you like C or D? ")
            i = inputchecker(2, second)

def inputchecker(n, userinput):          
    if n == 1:
        if userinput in ("A", "B"):
            print("You chose wisely.")
            return 2
        else:
            getusage(i)
            return i
    elif n == 2:
        if userinput in ("C", "D"):
            print("You chose wisely.")
        else:
            getusage(i)
            return i

如果将它简化为单个函数,可能会更好。没有理由需要拆分。

答案 2 :(得分:0)

我当然会避免递归调用。另外,我会让验证函数返回一个布尔值而不是下一个问题的数字。由于你无论如何都要按顺序提出问题,这似乎只会让你的代码读者感到困惑。

另外我会让验证始终返回一些东西 - 你永远不会知道:第一个参数也可能是错误的:

def getinput():
    valid = False
    while not valid:
        first = input("Would you like A or B? ")
        valid = inputIsValid(1, first)
    valid = False
    while not valid:
        second = input("Would you like C or D? ")
        valid = inputIsValid(2, second)
    return [first, second]

def inputIsValid(n, userinput):    
    valid = False
    if n == 1:
        valid = userinput in ("A", "B")
    elif n == 2:
        valid = userinput in ("C", "D")
    if valid:
        print("You chose wisely.")
    else:
        usage(n)
    return valid

def usage(u):
    if u == 1:
        print("Usage: Just A or B please.") 
    elif u == 2:
        print("Usage: Just C or D please.") 

getinput()