2016-11-22 136 views
4

我在我的R.Pi上學習Python,並且遇到了一個小障礙。在我看來,下面的代碼會將「inputchecker」功能保留在內存中,並返回到「getinput」功能。嵌套函數Pythonic?

這是錯的代碼?它應該完全不同嗎?

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) 
+0

這不完全是Python的,因爲這會導致if語句與不可預見的真正問題,這不是隻蟒蛇限制。所有語言都支持這種「黑客」。最好使用while循環,除非您經常使用while循環將其放入函數中。 – ProgramFast

回答

2

不,嵌套函數中的名稱getinput不會創建引用。每次調用_tryagain_都會被查找,因爲它是全球性的。這並不重要,因爲在Python退出時將模塊作爲一個整體清除,所以在這裏沒有真正的內存泄漏機會。

但是,您正在使用遞歸來要求用戶輸入,並且您的代碼很難遵循。改用一個簡單的循環,參見Asking the user for input until they give a valid response

+0

偉大的反饋謝謝你。現在我有更多的方向歡呼。 – Benjo

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 

它可能甚至會更好,如果你簡化成一個單一的功能更好。沒有理由需要分割。

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

要回答你的「Python化」問題:雖然蟒蛇可以做函數式編程,它是not designed。語法有點難懂,語言缺少一些features。其中一些缺失的特徵意味着遞歸是slow

所以,我會堅持到imperitave編程是「Python的」

+0

這與函數式編程有什麼關係?代碼*是必要的。這裏沒有尾遞歸。並非所有的遞歸代碼都是功能代碼。 –