2016-08-21 7 views
11

나는 인터프리터에서 방금 놀고 있었고 이해할 수없는 것을 발견했다. 하나의 요소로리스트를 가진 튜플을 생성하고 그리스트를 업데이트하려고하면 이상한 일이 발생합니다. 예를 들어, 내가 실행할 때이 :튜플 내에서 목록 업데이트

tup = (1,2,3,[4,5]) 
tup[3] += [6] 

내가 얻을 :

내가 예상 정확히 무엇
TypeError: 'tuple' object does not support item assignment 

. 내가 다시 튜플을 참조 할 때 다음, 내가 얻을 : 그래서 목록이 사실 파이썬은 예외가 발생했습니다에도 불구하고 업데이트 된

>>> tup 
(1, 2, 3, [4, 5, 6]) 

. 어떻게 작동합니까? 나는 이런 식으로 실제로하고 싶은 시나리오를 상상할 수는 없지만 아직도 어떤 일이 벌어지고 있는지 이해하고 싶습니다. 고맙습니다.

답변

27

실제로는 Python docs에 설명되어 있습니다.

수정 : 여기에 요약이 나와 있으므로보다 완벽한 답변을 얻을 수 있습니다. 우리가 +=를 사용하는 경우

  1. 는, 파이썬은 다음 후속 항목 할당의 반환 값을 사용하여 항목에 __iadd__ 마법 메소드를 호출합니다.
  2. 목록의 경우 __iadd__은 목록에서 extend을 호출 한 다음 목록을 반환하는 것과 같습니다.
  3. 우리가 tup[3] += [6]를 호출 할 때 따라서, 그것은 동일합니다 : 첫 번째 줄은 extend를 호출에 성공

    result = tup[3].extend([6]) 
    tup[3] = result 
    
  4. :

    result = tup[3].__iadd__([6]) 
    tup[3] = result 
    
  5. # 2에서, 우리는이를 확인할 수에 해당합니다 목록에 있으며, 목록이 변경 가능하기 때문에 업데이트됩니다. 그러나 튜플을 변경할 수 없으므로 이후 할당이 실패하고 오류가 발생합니다.

+2

나는 확장이 단지'tup [3] .__ iadd __ ([6])이 아니기 때문에 그것이 도움이 될 것이라고 생각합니다. 'tup [3] = tup [3] .__ iadd __ ([6])'입니다. 'list .__ iadd__'가 돌연변이를 일으키는 것과 똑같은 객체를 반환하는 것이 편리합니다. – zondo

+0

문서 링크를 가져 주셔서 감사합니다! 그것은 큰 도움이됩니다. –

+0

감사합니다. 전 문서에서이 문제를 발견하지 못했습니다. 따라서이 튜토리얼에 대한 이해를 돕기 위해 기본적으로 tup [3] .__ iadd __ ([6])을 수행하고 있으므로 파이썬에서 튜플에 대한 항목 할당을 시도했기 때문에 목록이 업데이트됩니다. 그래서 나는 그것이 실패했다고 말하는 예외를 얻었지만 그 시점까지 우리는 이미 목록을 갱신 했습니까? –