-
[python] 파이썬의 변수, 객체, 그리고 참조 주소코딩 연습/코딩배우기 2020. 9. 19. 19:49
■ 파이썬에서 모든 자료(type)는 객체이기 때문에 변수에 객체를 대입하면 특정 메모리 주소를 할당받게 되고, 그 변수를 다른 변수에 대입하면 같은 객체 주소를 참조하게 된다.
■ 파이썬의 기본 자료형 중 int, float와 수정불가(immutable)한 객체인 str, tuple 등은 그 변수의 대입(할당) 값을 수정하면 다른 주소를 참조하게 되어 같은 변수라고 볼 수 없지만, 수정가능(mutable)한 객체는 값을 수정해도 참조 주소를 유지한다.
a = 10 print(id(a)) # 140729182426208 b = a print(id(b)) # 140729182426208 print(a is b) # True a = 20 print(id(a)) # 140729182426528 --> 참조 주소 다름 s = 'python' print(id(s)) # 1313064861120 #s[0] = 'P' # TypeError: 'str' object does not support item assignment s = s.replace('p', 'P') print(s) # Python print(id(s)) # 1313155574616 --> 참조 주소가 다름 lst_a = [1, 2, 3, 4] lst_b = lst_a print(id(lst_a)) # 1313157490696 print(lst_a is lst_b) # True lst_a[0] = 10 print(lst_a, lst_b) # [10, 2, 3, 4] [10, 2, 3, 4] print(id(lst_a)) # 1313157490696 --> 내용 수정되었지만, 참조 주소 같음 print(lst_a is lst_b) # True
■ 함수에 의한 객체(리스트) 값의 수정 여부와 수정 안되게 하는 방법
def mutable_a(l1): l1.append(9) print(l1) lst = [1, 3, 5, 7] mutable_a(lst) # [1, 3, 5, 7, 9] print(lst) # [1, 3, 5, 7, 9] --> 원본 수정됨 def mutable_b(l1): l2 = l1 l2.append(9) print(l2) lst2 = [1, 3, 5, 7] mutable_b(lst2) # [1, 3, 5, 7, 9] print(lst2) # [1, 3, 5, 7, 9] --> 원본 수정됨 def mutable_c(l1): l2 = l1[:] # 리스트 슬라이싱으로 객체 대입 l2.append(9) print(l2) lst3 = [1, 3, 5, 7] mutable_c(lst3) # [1, 3, 5, 7, 9] print(lst3) # [1, 3, 5, 7] --> 원본 수정 안됨 import copy def mutable_d(l1): l2 = copy.copy(l1) # copy 함수 이용 l2.append(9) print(l2) lst4 = [1, 3, 5, 7] mutable_d(lst4) # [1, 3, 5, 7, 9] print(lst4) # [1, 3, 5, 7] --> 원본 수정 안됨
■ 얕은 복사 copy.copy(), 깊은 복사 copy.deepcopy() 알아보기
lst5 = ['outer', ['inner']] cp = copy.copy(lst5) dcp = copy.deepcopy(lst5) print('lst5 :', lst5) print(' cp :', cp) print(' dcp :', dcp) print('\n복사 결과') print(id(lst5), id(lst5[0]), id(lst5[1])) print(id(cp), id(cp[0]), id(cp[1])) print(id(dcp), id(dcp[0]), id(dcp[1])) # copy, deepcopy 모두 리스트 값을 복사하였으나(참조 주소 다름) # copy()의 경우 outer, [inner] 모두 참조 주소가 같은 반면, # deepccopy()의 경우 outer는 같으나 [inner]는 참조 주소가 다른 것을 볼 수 있다. lst5.append('add_outer') print('\n리스트에 값 추가 결과') print('lst5 :', lst5) print(' cp :', cp) print(' dcp :', dcp) # lst5에만 추가됨 lst5[1].append('add_inner') print('\n내부 리스트에 값 추가 결과') print('lst5 :', lst5) print(' cp :', cp) print(' dcp :', dcp) # lst5, cp 두 개에 추가됨 (deepcopy는 영향 없음) print('\n값 추가 후 참조 주소 변화 없음(mutable 객체(리스트)') print(id(lst5), id(lst5[0]), id(lst5[1])) print(id(cp), id(cp[0]), id(cp[1])) print(id(dcp), id(dcp[0]), id(dcp[1])) [실행 결과] lst5 : ['outer', ['inner']] cp : ['outer', ['inner']] dcp : ['outer', ['inner']] 복사 결과 1313157491400 1313065028272 1313157639816 1313157492424 1313065028272 1313157639816 1313157636488 1313065028272 1313157525320 리스트에 값 추가 결과 lst5 : ['outer', ['inner'], 'add_outer'] cp : ['outer', ['inner']] dcp : ['outer', ['inner']] 내부 리스트에 값 추가 결과 lst5 : ['outer', ['inner', 'add_inner'], 'add_outer'] cp : ['outer', ['inner', 'add_inner']] dcp : ['outer', ['inner']] 값 추가 후 참조 주소 변화 없음(mutable 객체(리스트) 1313157491400 1313065028272 1313157639816 1313157492424 1313065028272 1313157639816 1313157636488 1313065028272 1313157525320
Life is Short, Use Python.
'코딩 연습 > 코딩배우기' 카테고리의 다른 글
[python] 파이썬 datetime(), time(), localtime() (0) 2020.09.20 [python] 파이썬 함수의 위치 인자, 키워드 인자 언패킹 (0) 2020.09.19 [python] 파이썬의 진수 변환(2진수, 8진수, 10진수, 16진수) (0) 2020.09.18 [python] 파이썬 스태틱(static) 메서드와 클래스(class) 메서드 (0) 2020.09.17 [python] 파이썬 데코레이터 (Decorator) (0) 2020.09.16