>>> t = (0, 1, [2, 3])


>>> t[2] += [4, 5]

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

TypeError: 'tuple' object does not support item assignment


여기까지는 상식적이다.


튜플은 불변 객체이므로 내부 원소에 할당을 허용하지 않는다.


-------------------------------------------------


그런데 에러를 씹고 t를 다시 참조해보면?


>>> t

(0, 1, [2, 3, 4, 5])


띠용~~


-------------------------------------------------


+=의 성질


__iadd__를 호출한다.

__iadd__가 없으면 __add__를 대신 호출하고 마치 __iadd__처럼 결과를 대입시켜준다.

불변 객체에 대해서는 __iadd__가 구현되어있어도 참조 안하고 __add__를 호출한 다음 결과값으로 새 객체를 만들어 리턴한다.

(리스트는 불변 객체가 아니나 튜플 안에 있으므로 불변인 것으로 해결될 것이다)


위에서 일어나는 일


튜플에 대한 할당 시도가 스택에 올라간다.

+= 연산이 스택에 올라간다.

+= 연산이 먼저 해결된다.(새로운 튜플을 만들어 리턴하여 t에 대입한다.)

할당 시도가 해결되어 에러가 난다.(그러나 에러의 대상은 이미 t를 떠났다.)


-------------------------------------------------


참고로 이런 건 당연히 에러도 안 뜨고 된다.


>>> t = (0, 1, [2, 3])


>>> t[2][1] += 1


>>> t

(0, 1, [2, 4])


튜플의 2번째 원소인 리스트의 값(자기 내용물의 주소범위를 가지고 있는 값) 자체는 안 건드렸기 때문에 의도 밖은 아니다.

첫번째 예제는 주소 범위 자체가 변했기 때문에 의도 외인 것이다.