以参数作为变量名赋值:为何能解决Python函数调用后外部变量未更新的问题?
Great question! Let's break this down step by step to clarify the mechanics, then explore other ways to implement this logic.
Why Your First Code Failed
In Python, simple types like int are immutable—you can't change their value in-place; you can only create a new object with a new value. When you pass A, B, C to my_sum, you're passing references to these immutable objects. Inside the function, z = x + y creates a new int object and assigns it to the local variable z—this doesn't touch the original C variable outside the function. Since you didn't capture the function's returned values, A, B, C stayed stuck to their initial values.
Why Assigning the Return Values Works
Your fix works because you're taking the three new values returned by my_sum and reassigning them to A, B, C. Each line like A, B, C = my_sum(A, B, C) tells Python:
- Take the first returned value and make
Apoint to it - Take the second returned value and make
Bpoint to it - Take the third returned value and make
Cpoint to it
This replaces the original references with the new objects created inside the function, so the variables now hold the updated values. It's a clean, functional approach that avoids side effects.
Alternative Implementations
Here are a few other ways to achieve the same result, depending on your use case:
1. Use a Mutable Container (e.g., List)
Since lists are mutable, modifying elements inside a list affects the original list outside the function. This removes the need to return and reassign values:
def my_sum(values): # Update the third element (matches z in your original function) values[2] = values[0] + values[1] # Initialize as a single list instead of separate variables abc = [1, 2, 0] my_sum(abc) abc = [abc[1], abc[2], abc[0]] # Reorder like your original call sequence my_sum(abc) abc = [abc[1], abc[2], abc[0]] my_sum(abc) abc = [abc[1], abc[2], abc[0]] my_sum(abc) abc = [abc[1], abc[2], abc[0]] my_sum(abc) print(abc[0], abc[1], abc[2]) # Output: 21 8 13
2. Use a Class to Encapsulate State
If this logic is part of a larger program, using a class to hold your state (A, B, C) makes the code more organized and reusable:
class SumTracker: def __init__(self): self.a = 1 self.b = 2 self.c = 0 def update_sum(self): self.c = self.a + self.b def cycle_values(self): # Reorder variables to match your original call sequence self.a, self.b, self.c = self.b, self.c, self.a tracker = SumTracker() tracker.update_sum() tracker.cycle_values() tracker.update_sum() tracker.cycle_values() tracker.update_sum() tracker.cycle_values() tracker.update_sum() tracker.cycle_values() tracker.update_sum() print(tracker.a, tracker.b, tracker.c) # Output: 21 8 13
3. Use Global Variables (Not Recommended)
You could use the global keyword to modify the original variables directly inside the function, but this is generally bad practice—it makes code harder to debug, test, and reuse:
A = 1 B = 2 C = 0 def my_sum(x, y): global C C = x + y my_sum(A, B) A, B, C = B, C, A my_sum(B, C) A, B, C = B, C, A my_sum(C, A) A, B, C = B, C, A my_sum(A, B) A, B, C = B, C, A my_sum(B, C) print(A, B, C) # Output: 21 8 13
Your original fix (returning and reassigning values) is actually one of the best approaches here—it keeps the function pure (no side effects) and easy to reason about.
内容的提问来源于stack exchange,提问作者g_barsani113

