You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python控制台记事本菜单:如何避免嵌套调用的异常干扰?

Hey Sam, let's break down your problem and fix it step by step!

1. Fix the Overly Broad Exception Handling

Your actionChooser uses a bare except: clause, which catches all types of exceptions—including errors like IndexError from readNote (when a user enters a number outside the range of your note list). This causes errors that should be handled in readNote to accidentally trigger the except block in actionChooser, messing up your logic flow.

Here's how to fix it:

  • Only catch the specific exception you expect: ValueError (which happens when converting the input string to an integer fails)
  • Add a check to validate the note index before calling readNote, to avoid index errors entirely

Updated actionChooser code:

def actionChooser(action):
    try:
        action_num = int(action) - 1
        # Validate the index first to avoid IndexError in readNote
        if 0 <= action_num < len(noteList):
            readNote(action_num)
        else:
            print("Invalid note number!\n")
    except ValueError:  # Only catch conversion-to-int failures
        action_lower = action.lower()
        if action_lower == "n":
            newNote()
        elif action_lower == "d":
            deleteNote()
        elif action_lower == "e":
            exit()
        else:
            print("Invalid action.\n")

If you want to handle errors directly in readNote, you can add a targeted try-except there too:

def readNote(noteNumber):
    try:
        print(f"\n{noteList[noteNumber][0].upper()}")
        print(noteList[noteNumber][1])
    except IndexError:
        print("That note doesn't exist!\n")

2. Optimize the Menu Structure (Avoid Recursion)

Right now, every menu function calls mainMenu() at the end, which uses recursion. While this works for small use cases, repeated operations will eventually cause a stack overflow (Python has a limit on recursive depth). A better approach is to use a main loop to control the menu flow.

Here's a refactored, more robust version of your code:

noteList = [["Here goes the title", "Here goes the text", "Here goes the date"], ["Example", "Text Text Text Text Text Text Text Text", "08/08/2020"]]

def show_main_menu():
    print("NOTES")
    print("Write:")
    print('-The number of the note to read;')
    print('[N] to create a [N]ew note;')
    print('[D] to [D]elete a note;')
    print('[E] to [E]xit;')
    
    if len(noteList) == 0:
        print("\nYou have no notes.")
    else:
        print("\nSaved notes:")
        # Use enumerate for cleaner index handling
        for idx, note in enumerate(noteList, start=1):
            print(f"{idx}-{note[0]}")

def handle_action(action):
    cleaned_action = action.strip().lower()
    if cleaned_action.isdigit():
        action_num = int(cleaned_action) - 1
        if 0 <= action_num < len(noteList):
            readNote(action_num)
        else:
            print("Invalid note number!\n")
    else:
        if cleaned_action == "n":
            newNote()
        elif cleaned_action == "d":
            deleteNote()
        elif cleaned_action == "e":
            print("Exiting...")
            exit()
        else:
            print("Invalid action.\n")

def readNote(noteNumber):
    print(f"\n{noteList[noteNumber][0].upper()}")
    print(noteList[noteNumber][1])
    # Add a pause to let the user read the note before returning
    input("\nPress Enter to return to main menu...")
    print()

# Example implementation for missing functions
def newNote():
    title = input("Enter note title: ")
    content = input("Enter note content: ")
    from datetime import datetime
    date = datetime.now().strftime("%d/%m/%Y")
    noteList.append([title, content, date])
    print("Note saved!\n")

def deleteNote():
    if len(noteList) == 0:
        print("No notes to delete!\n")
        return
    idx_input = input("Enter the number of the note to delete: ")
    if idx_input.isdigit():
        delete_num = int(idx_input) - 1
        if 0 <= delete_num < len(noteList):
            removed_note = noteList.pop(delete_num)
            print(f"Deleted note: {removed_note[0]}\n")
        else:
            print("Invalid note number!\n")
    else:
        print("Please enter a valid number!\n")

# Main loop entry point
if __name__ == "__main__":
    while True:
        show_main_menu()
        user_action = input("Choose an action: ")
        handle_action(user_action)

Why this structure is better:

  • Uses a while True loop instead of recursion, eliminating stack overflow risks and making the flow more controllable
  • Splits menu display and action handling into separate functions, following the single-responsibility principle for cleaner code
  • Adds user-friendly pauses after actions (like reading a note)
  • Uses enumerate to simplify note list iteration
  • Cleans user input with strip() to handle accidental spaces

Quick Extra Tips

  • Never use bare except:—always specify the exact exception types you want to handle (this prevents catching unexpected errors like KeyboardInterrupt)
  • Use the datetime module to auto-generate note dates instead of manual input
  • Add input validation for all user inputs to make the program more resilient

内容的提问来源于stack exchange,提问作者SamFF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 20:12:35