【问题标题】:Is Nesting Functions Pythonic?嵌套函数是 Pythonic 的吗?
【发布时间】:2017-04-06 12:11:06
【问题描述】:

我正在我的 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)

【问题讨论】:

  • 它并不完全是 pythonic,因为它可能会导致无法预料的 true if 语句出现问题,而且这不仅限于 python。所有语言都支持这种“hack”。最好使用 while 循环,除非您经常使用 while 循环以将其放入函数中。

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


【解决方案1】:

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

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

【讨论】:

  • 很好的反馈,谢谢。我现在有了更多的方向,欢呼。
【解决方案2】:

让两个函数无限地相互调用并不是最好的控制流。使用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

如果你把它简化成一个函数可能会更好。没有理由需要拆分。

【讨论】:

    【解决方案3】:

    我当然会避免递归调用。另外,我会让验证函数返回一个布尔值,而不是下一个问题的数字。由于您按顺序提出问题,这似乎只会让您的代码读者复杂化。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 2010-09-08
      • 1970-01-01
      • 2018-07-11
      • 1970-01-01
      • 1970-01-01
      • 2013-02-23
      相关资源
      最近更新 更多