2017-04-13 39 views
0

我想保持一個用戶已經吃掉了多少卡路里的熱量,然後將它插入到數據庫中,同時也給出了用戶已經吃掉卡路里量的反饋。當我定義TotalCalories之外的功能並將其設置爲一個全局變量(以便它可以在其他函數內部使用),我得到的錯誤UnboundLocalError: local variable 'TotalCalories' referenced before assignment如何在函數內部保持運行總數並允許在函數外部訪問?

def FoodSelection(choice): 
    global CurrentPupil 
    CurrentPupil = "" 
    global FoodSelectionWindow 
    FoodSelectionWindow = Toplevel() 
    FoodSelectionWindow.configure(bg="black") 

    DateAdded = datetime.date.today() 
    TimeTaken = 0 
    NoFoodOption = 0 

    #The validation timer starts here: 

    while TimeTaken < 2: 
     time.sleep(60) 
     TimeTaken = TimeTaken +1 

    #and ends here 

    class food(): 
     def __init__(self, name = "no name", calories = 0, photo = ""): 
      self.name = name 
      self.calories = calories 
      self.photo = photo 

    BoiledEggs = food("Boiled Egg", 155, PhotoImage(file="BoiledEgg.gif")) 
    ScrambledEggs = food("Scrambled Egg", 148, PhotoImage(file="ScrambledEgg.gif")) 
    FriedEggs = food("Fried Egg", 196, PhotoImage(file="FriedEgg.gif")) 
    PoachedEggs = food ("Poached Egg", 143, PhotoImage(file="PoachedEgg.gif")) 
    Toast = food("Toast", 313, PhotoImage(file="Toast.gif")) 
    Bacon = food("Bacon", 514, PhotoImage(file="Bacon.gif")) 
    Cereal = food("Cereal", 379, PhotoImage(file="Cereal.gif")) 
    Porridge = food("Porridge", 68, PhotoImage(file="Cereal.gif")) 
    NoBreakfast = food("No Breakfast", 0, PhotoImage(file="NoBreakfast.gif")) 

    def NoFood(): 
     FoodChoices("No Food") 

    def BoiledEggsFunct(): 
     FoodChoices("Boiled Eggs") 

    def FriedEggsFunct(): 
     FoodChoices("Fried Eggs") 

    def ScrambledEggsFunct(): 
     FoodChoices("Scrambled Eggs") 

    def PoachedEggsFunct(): 
     FoodChoices("Poached Eggs") 

    def ToastFunct(): 
     FoodChoices("Toast") 

    def BaconFunct(): 
     FoodChoices("Bacon") 

    def CerealFunct(): 
     FoodChoices("Cereal") 

    def PorridgeFunct(): 
     FoodChoices("Porridge") 

    global TotalCalories 
    TotalCalories = 0 

    def FoodChoices(selection): 

     if selection == "No Food": 
      TotalCalories = NoBreakfast.calories 

     elif selection == "Boiled Eggs": 
      TotalCalories = BoiledEggs.calories + TotalCalories 

     elif selection == "Fried Eggs": 
      TotalCalories = FriedEggs.calories + TotalCalories 

     elif selection == "Scrambled Eggs": 
      TotalCalories = ScrambledEggs.calories + TotalCalories 

     elif selection == "Poached Eggs": 
      TotalCalories = PoachedEggs.calories + TotalCalories 

     elif selection == "Toast": 
      TotalCalories = Toast.calories + TotalCalories 

     elif selection == "Bacon": 
      TotalCalories = Bacon.calories + TotalCalories 

     elif selection == "Cereal": 
      TotalCalories = Cereal.calories + TotalCalories 

     elif selection == "Porridge": 
      TotalCalories = Porridge.calories + TotalCalories 


     if choice == 'chris': 
      CurrentPupil = "Chris" 
      with db: 
       cursor.execute(''' INSERT INTO 'Breakfast_History' (CaloriesTotal, DateAddded, PupilNames, PupilID) VALUES (?,?,?,?)''', 
           ([TotalCalories, DateAdded, CurrentPupil,"1"])) 
     elif choice == 'josh': 
      CurrentPupil = "Josh" 
      with db: 
       cursor.execute(''' INSERT INTO 'Breakfast_History' (CaloriesTotal, DateAddded, PupilNames, PupilID) VALUES (?,?,?,?)''', 
          ([TotalCalories, DateAdded, CurrentPupil,"2"])) 
     elif choice == 'sam': 
      CurrentPupil = "Sam" 
      with db: 
       cursor.execute(''' INSERT INTO 'Breakfast_History' (CaloriesTotal, DateAddded, PupilNames, PupilID) VALUES (?,?,?,?)''', 
          ([TotalCalories, DateAdded, CurrentPupil,"3"])) 
     elif choice == 'daniel': 
      CurrentPupl = "Daniel" 
      with db: 
       cursor.execute(''' INSERT INTO 'Breakfast_History' (CaloriesTotal, DateAddded, PupilNames, PupillID) VALUES (?,?,?,?)''', 
          ([TotalCalories, DateAdded, CurrentPupil, "4"])) 
     elif choice == 'jim': 
      CurrentPupil = "Jim" 
      with db: 
       cursor.execute(''' INSERT INTO 'Breakfast_History' (CaloriesTotal, DateAddded, PupilNames, PupilID) VALUES (?,?,?,?)''', 
          ([TotalCalories, DateAdded, CurrentPupil,"5"])) 

     elif choice == 'sean': 
      CurrentPupil = "Sean" 
      with db: 
       cursor.execute(''' INSERT INTO 'Breakfast_History' (CaloriesTotal, DateAddded, PupilNames, PupilID) VALUES (?,?,?,?)''', 
          ([TotalCalories, DateAdded, CurrentPupil,"6"])) 

     db.commit() 

    def FeedbackScreen(): 
     FinishWindow = Toplevel() 

     if TotalCalories > 0 and TotalCalories < 1000: 
      HealthyLabel = Label(FinishWindow, text = "Congratulations, you are healthy!", font=("Comic Sans MS", 25), fg = "light green", 
        bg = "black") 
      HealthyLabel.grid(columnspan=10) 

     elif TotalCalories > 1000: 
      UnhealthyLabel = Label(FinishWindow, text = "Try to eat healthier tomorrow. See personalised advice", font=("Comic Sans MS", 25), fg = "yellow", 
        bg = "black") 
      UnhealthyLabel.grid(columnspan=10) 

     elif NoFoodOption == 1: 
      NoFoodLabel = Label(FinishWindow, text = "Not eating can be harmful to your health. See personalised advice", font=("Comic Sans MS", 25), fg = "red", 
        bg = "black") 
      NoFoodLabel.grid(columnspan=10) 

     else: 
      Error = Label(FinishWindow, text = "error", font=("Comic Sans MS", 25), fg = "red", 
        bg = "black") 
      NoFoodLabel.grid(columnspan=10)  

正如你所看到的,我需要在使用TotalCalories代碼中的各種函數,所以我認爲通過將其作爲全局變量,我可以做到這一點。

有什麼建議嗎?

+1

目前幾乎可以肯定沒有理由有這樣的嵌套結構。你只需要從一個函數中'返回'這個值,該函數將它分配給任何被稱爲函數的函數。 – roganjosh

回答

1

這裏是你的問題的MCVE

global TotalCalories 
TotalCalories = 0 

def FoodChoices(selection): 

    if selection == "No Food": 
     TotalCalories = 100 

    elif selection == "Boiled Eggs": 
     TotalCalories = 100 + TotalCalories 

FoodChoices("Boiled Eggs") 

運行這段代碼產生這樣的輸出:

$ python test.py 
Traceback (most recent call last): 
    File "test.py", line 13, in <module> 
    FoodChoices("Boiled Eggs") 
    File "test.py", line 11, in FoodChoices 
    TotalCalories = 100 + TotalCalories 
UnboundLocalError: local variable 'TotalCalories' referenced before assignment 

和插入global TotalCalories到功能使它消失:

def FoodChoices(selection): 
    global TotalCalories 

    if selection == "No Food": 
     TotalCalories = 100 

    elif selection == "Boiled Eggs": 
     TotalCalories = 100 + TotalCalories 

Python需要在函數中聲明全局名稱n你打算如何使用它,如果你打算重新整合全球。如果您只是從中讀取數據或對其進行變異,那麼您可以在函數中沒有聲明的情況下離開。

+0

這很好,謝謝。 – jamielevy

0

您可能沒有考慮過替代方案。在Python中,爲了某些目的,可以使對象看起來像一個函數。然後,您可以累積在對象變量中調用函數時收集的信息。在你的情況下,TotalCalories可能是一個對象的變量。竅門是在對象中使用名稱__call__作爲方法;變成'可調用'。

class FoodSelection: 
    def __init__ (self): 
     self.TotalCalories = 0 
    def __call__ (self, choice): 
     if choice == 'potatoes': 
      print (choice, ''': eat as little as possible!''') 
      self.TotalCalories += 10000 
     elif choice == 'salad': 
      print (choice, ': good choice!') 
      self.TotalCalories += 0 
     else: 
      print (choice, ''': sorry, don't understand that''') 


foodSelection = FoodSelection() 

foodSelection('potatoes') 
print (foodSelection.TotalCalories) 

foodSelection('salad') 
print (foodSelection.TotalCalories) 

foodSelection('bacon') 
print (foodSelection.TotalCalories) 

foodSelection('potatoes') 
print (foodSelection.TotalCalories) 

下面是輸出:

potatoes : eat as little as possible! 
10000 
salad : good choice! 
10000 
bacon : sorry, don't understand that 
10000 
potatoes : eat as little as possible! 
20000 
相關問題