Python 3 Tkinter出现NameError: 'price_overall_release'未定义求助
Ah, I see the issue here! The global keyword isn't working because your price_overall_release variable isn't actually in the module-level scope—it's defined inside another function (the one that sets up your Toplevel window). Let's break down why this happens and how to fix it.
Root Cause
When you use global price_overall_release, Python looks for that variable in the top-level (module) scope of your script. But since you've defined price_overall_release = 0 inside the function that creates your Toplevel window, it lives in that outer function's local scope—not the module scope. So Python can't find it when you try to reference it with global, hence the NameError.
Fix 1: Use nonlocal Instead of global
The nonlocal keyword is designed exactly for this scenario: when you want to modify a variable from an enclosing (non-module) function scope. Just replace global with nonlocal in your release_button function:
def release_button(add_or_sub, game_id): nonlocal price_overall_release # Changed from global to nonlocal if add_or_sub == "add": price_releases[game_id] = float(price_releases[game_id]) price_overall_release = price_overall_release + price_releases[game_id] price_releases[game_id] = str(price_releases[game_id]) # Rest of your add logic... else: # Rest of your sub logic...
This tells Python to look for price_overall_release in the nearest enclosing function scope (the one holding your Toplevel setup), and it will work as expected.
Fix 2: Use a Mutable Object (Avoid Scoping Keywords Altogether)
If you prefer not to mess with nonlocal or global, you can use a mutable object like a list to hold your total price. Since lists are mutable, you can modify their contents without needing explicit scope declarations:
First, initialize the variable as a list in your outer function:
price_overall_release = [0] # Use a list instead of a plain float
Then update it in your release_button function:
def release_button(add_or_sub, game_id): price_releases[game_id] = float(price_releases[game_id]) if add_or_sub == "add": price_overall_release[0] += price_releases[game_id] else: price_overall_release[0] -= price_releases[game_id] price_releases[game_id] = str(price_releases[game_id]) # Update your label with the new value current_total = str(price_overall_release[0]) # Rest of your label logic...
This works because you're modifying the contents of the list (mutable) rather than reassigning the variable itself, so Python doesn't need scope keywords.
Bonus Tip: Optimize Label Updates
Right now, you're creating a new Label every time the button is clicked, which is inefficient. Instead, create the label once in your outer function, then just update its text when the button is pressed:
In your Toplevel setup function:
# Create labels once initially price_overall_release = 0 label_overallprice_releases = Label(new_release_window, text="$0", bg=releases_price_colour, fg="black", relief="sunken", borderwidth=1, font=gui_font_10) label_overallprice_releases.grid(row=12, column=3, padx=7.5, pady=space_between) amount_ordered_release = Label(new_release_window, text=amount_release, bg=releases_price_colour, fg="black", borderwidth=1, font=gui_font_10) amount_ordered_release.grid(...) # Set its grid position once
Then in release_button, replace label creation with:
# Update existing label instead of creating a new one label_overallprice_releases.config(text=f"${price_overall_release:.2f}") # Update amount_ordered_release similarly if needed
This keeps your code cleaner and runs smoother.
Content of the question来源于Stack Exchange,提问作者Simone Rizzuto

