Python类内赋值局部变量后修改为何同步改变self关联对象?
var Changes self.test_json in Python Hey there! Let's clear up this confusion—you're right that Python doesn't have pointers like C/C++, but it does use object references, which is exactly what's causing this behavior. Let's break it down step by step:
1. Python's Variable Model: References, Not Values
In Python, every variable acts as a reference to an object, not a direct container for a value. When you run this line:
var = test.test_json
You're not copying the SimpleNamespace object that test.test_json points to—you're just making var point to the exact same object in memory. So var and self.test_json are two different names tied to one shared object.
That's why when you modify var.test_id = 6, you're actually changing the test_id attribute of that single shared object. Any other variable pointing to that object (like self.test_json) will automatically see the updated value.
2. Your Code's Misstep
You mentioned wanting var to copy just the test_id value, but your code is assigning the entire SimpleNamespace object to var, not just the integer value of test_id. If you only wanted to copy the test_id value, you'd do this instead:
var_test_id = test.test_json.test_id # Copies the integer value (5) var_test_id = 6 # This won't affect self.test_json.test_id at all
Since integers are immutable in Python, assigning a new value to var_test_id just makes that variable point to a new integer object (6), leaving the original 5 completely untouched.
3. Fixing the Object Copy Issue
If you need to create a separate copy of the entire SimpleNamespace object (so modifying var doesn't impact the original), use Python's copy module to make a shallow or deep copy:
from types import SimpleNamespace import json import copy # Add this import class Test: def __init__(self, json_data): self.tests = json_data.tests self.test_json = "" def do_something(self): for test in self.tests: # Make a shallow copy of the SimpleNamespace object var = copy.copy(test.test_json) self.test_json = test.test_json # Points to the original object print("The self.test_json is: " + str(self.test_json.test_id)) print("test_json is: " + str(var.test_id)) var.test_id = 6 print("(should be 5, unchanged) The self.test_json is: " + str(self.test_json.test_id)) print("(should be 6, changed) test_json is: " + str(var.test_id)) if __name__ == '__main__': json_data = b'{"tests": [{"test_json": {"test_id":5 }}]}' data_as_simple_namespace = json.loads(json_data, object_hook=lambda d: SimpleNamespace(**d)) t = Test(data_as_simple_namespace) t.do_something()
Running this modified code will give you the output you expected:
The self.test_json is: 5 test_json is: 5 (should be 5, unchanged) The self.test_json is: 5 (should be 6, changed) test_json is: 6
- Use
copy.copy()for shallow copies (works great for flat objects like yourSimpleNamespace). - Use
copy.deepcopy()if your object has nested mutable objects (like anotherSimpleNamespaceinside it), to ensure all nested layers are duplicated.
内容的提问来源于stack exchange,提问作者avico34

