Tuple là immutable, nhưng nếu chứa mutable object (như list), nội dung của object đó có thể thay đổi, dù gán lại tuple thất bại.
Ví dụ gây nhầm lẫn
tupl = (5, 7, 9, [1, 4]) tupl[3] += [6, 8]
Kết quả
TypeError: 'tuple' object does not support item assignment # NHƯNG tuple giờ thành: (5, 7, 9, [1, 4, 6, 8])
Phân tích Bytecode (dis)
import dis
def immut_func():
tupl = (5, 7, 9, [1, 4])
tupl[3] += [6, 8]
dis.dis(immut_func)
Bytecode quan trọng
3 24 LOAD_FAST 0 (tupl)
27 LOAD_CONST 6 (3)
30 DUP_TOPX 2
33 BINARY_SUBSCR # Lấy tupl[3] (list [1,4])
34 LOAD_CONST 7 (6)
37 LOAD_CONST 8 (8)
40 BUILD_LIST 2 # Tạo list [6,8]
43 INPLACE_ADD # [1,4] += [6,8] -> [1,4,6,8] (THÀNH CÔNG!)
44 ROT_THREE
45 STORE_SUBSCR # Gán lại tupl[3] = list mới -> LỖI TẠI ĐÂY!
46 LOAD_CONST 0 (None)
49 RETURN_VALUE
Giải thích
INPLACE_ADD(bước 43) sửa đổi list in-place thành công → list bên trong tuple thay đổi.STORE_SUBSCR(bước 45) cố gắng gán lại slot index 3 của tuple → TypeError vì tuple immutable.- Kết quả: List đã bị sửa đổi, nhưng gán lại tuple thất bại.
Bài học
KHÔNG BAO GIỜ** đặt mutable object (list, dict, set) vào tuple nếu bạn định sửa đổi chúng. Dùng list của list, hoặc dataclass/namedtuple.