변수에 누적 대입과 객체에 누적 대입의 차이를 그림으로 이해

※ 다른 분의 기사의 코멘트에 썼습니다만, 여러분에게도 알고 싶어서 기사로 했습니다.

객체(값) 및 변수



파이썬에서는 None, 숫자, 함수, 클래스, 메소드, 모듈 등이 모두 객체 (어떤 클래스의 인스턴스)로 변환됩니다.
변수는 오브젝트에 대한 참조 값인 오브젝트 id를 보유합니다. 모든 객체를 할당할 수 있습니다. 다른 유형의 개체를 다시 할당할 수도 있습니다.
변수는 변수 이름을 사전 키로, 객체 id를 사전 값으로 변수 사전에 저장합니다. 변수 사전의 내용은 vars 함수, locals 함수, globals 함수에서 확인할 수 있습니다.
목록은 객체 id의 배열입니다. 배열 요소마다 다른 형태의 객체를 대입·재대입할 수도 있습니다.

변수 대입·재대입




>>> id(1)
15812500000
>>> type(1)
<class'int'>
>>> 1 .__class__    # 小数点に解釈されないようにドットの前に空白を入れる
<class'int'>
>>> 1 .real
1
>>> id(2)
15812500032
>>> a = 1
>>> id(a)
15812500000
>>> a = 2
>>> id(a)
15812500032
>>> vars()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class'_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>,
 'a': 2}

변수에의 누산 대입 그 1:이뮤터블 오브젝트의 경우


+= 와 같은 대입을 누산 대입이라고 합니다.
Python의 누적 할당은 변수에 할당된 객체가 이뮤터블(불변) 객체인지 뮤터블(가변) 객체인지에 따라 동작이 다릅니다.
int 형과 같은 이뮤터블 오브젝트의 경우는, 아래 그림과 같이 다른 오브젝트를 재대입합니다.


>>> a = 2
>>> id(a)
15812500032
>>> a += 1
>>> id(a)
15812500064

목록 객체




>>> id(1)
15812500000
>>> id(2)
15812500032
>>> id(3)
15812500064
>>> a = [1, 2, 3]
>>> id(a)
123145300973832
>>> type(a)
<class'list'>
>>> a.__class__
<class'list'>
>>> len(a)
3
>>> a.__len__()
3
>>> for ele in a:
...     print(ele, type(ele), id(ele))
...
1 <class'int'> 15812500000
2 <class'int'> 15812500032
3 <class'int'> 15812500064
>>> vars()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class'_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>,
 'a': [1, 2, 3],
 'ele': 3}

객체에 누적 할당




>>> a = [1, 2, 3]
>>> id(a[0])
15812500000
>>> a[0] += 1
>>> id(a[0])
15812500032
>>> id(a[1])
15812500032
-5 ~ 256의 정수 값 (int 형 객체)은 자주 사용되는 값으로 객체가 캐시되어 공유 재사용되므로 a[0]a[1]의 객체 id가 동일합니다. 있습니다.
오브젝트 지향의 디자인 패턴 로 말하는 「 flyweight 패턴 」가 사용되고 있습니다.

변수에의 누산 대입 그 2:뮤터블 오브젝트의 경우



리스트는 뮤터블 오브젝트이기 때문에, int 형 오브젝트의 경우와는 동작이 다릅니다.
아래 그림과 같이 오브젝트에 처리를 의뢰해, 오브젝트 자신이 오브젝트 내용을 변경합니다.


>>> a = [1, 2, 3]
>>> id(a)
123145300973832
>>> hasattr(a, '__iadd__')
True
>>> hasattr(2, '__iadd__')
False
>>> a += [4]
>>> id(a)
123145300973832
>>> len(a)
4
>>> a.__len__()
4
>>> id(a[3])
15812500096

참고



누적 할당 문장 : htps : // / cs. py 응. 오 rg / 그럼 / 3 / 레후 렌세 / mp ぇ_stmts. html
누산 할당 방법 : htps : // / cs. py 응. 오 rg / 그럼 / 3 / 레후 렌세 / 혼자서 l. html # b b ct. __이아 d__

좋은 웹페이지 즐겨찾기