λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
4️⃣ Python/Python 정리

[Python] 얕은 볡사 vs κΉŠμ€ 볡사 (feat. mutable, immutable 객체)

by seolhee2750 2022. 1. 30.

백쀀을 ν’€λ‹€κ°€ νŒŒμ΄μ¬μ€ λ³€μˆ˜λ₯Ό λŒ€μž…ν•  λ•Œ λ©”λͺ¨λ¦¬ μ£Όμ†Œκ°€ μ’€ λ‹€λ₯΄κ²Œ ν• λ‹Ήλ˜λŠ” 것 κ°™μ•„μ„œ

μ•Œμ•„λ³΄λ‹ˆ mutable, immutable 객체에 따라 λ‹€λ₯Έ 점이 μžˆλ‹€λŠ” 것을,, μ•Œκ²Œ λ˜μ—ˆλ‹€.

κ·Έλž˜μ„œ κ³΅λΆ€ν•˜κ³  μ“°λŠ” κΈ€ 〰️

 

πŸ“ mutable 객체와 immutable 객체의 비ꡐ

νŒŒμ΄μ¬μ—μ„œ κ°μ²΄λŠ” mutable, immutable둜 λ‚˜λˆŒ 수 μžˆλŠ”λ°,

list / set / dict 등은 mutable 객체, bool / int / str 등은 immutable 객체이닀.

 

πŸ‘‰ ꡬ뢄 방법

list 처럼 ν•˜λ‚˜ ν•˜λ‚˜μ˜ μš”μ†Œλ₯Ό λ°”κΏ”μ„œ μ €μž₯ν•  수 μžˆλŠ” κ°μ²΄λŠ” mutable,

str처럼 ν•˜λ‚˜ ν•˜λ‚˜μ˜ μš”μ†Œλ§Œμ„ λ°”κΏ” μ €μž₯ν•  수 μ—†λŠ” κ°μ²΄λŠ” immutable이라고 μƒκ°ν•˜λ©΄ 쉽닀.

 

μ•„λž˜ μ½”λ“œμ— list, str을 λŒ€ν‘œλ‘œ mutable 객체와 immutable 객체λ₯Ό κ°„λ‹¨νžˆ λΉ„κ΅ν–ˆλ‹€.

a = [1, 2, 3]
print(id(a)) # output : 4507373056
a[0] = 0
print(id(a)) # output : 4507373056

b = "abc"
print(id(b)) # output : 4507295344
# b[0] = "d" ν•˜λ‚˜μ˜ κΈ€μž λ³€κ²½ λΆˆκ°€
b = "def"
print(id(b)) # output : 4507969456
  • 리슀트 a에 [1, 2, 3]을 졜초둜 μ €μž₯ν–ˆκ³ , a[0]을 0으둜 λ°”κΏ”μ£Όμ—ˆλŠ”λ°,
    [0]에 0을 λ„£κΈ° μ „κ³Ό ν›„ λͺ¨λ‘ λ©”λͺ¨λ¦¬ μ£Όμ†Œκ°€ 같은 것을 확인할 수 μžˆλ‹€.
    μ΄λŠ” listκ°€ mutable 객체이기 λ•Œλ¬Έμ— κ°€λŠ₯ν•œ 것이닀.
  • str으둜 μ„ μ–Έλœ b의 κ²½μš°μ—λŠ” ν•˜λ‚˜ ν•˜λ‚˜μ˜ μš”μ†Œλ₯Ό λ°”κΏ€ μˆ˜λŠ” μ—†κ³ ,
    λ”°λΌμ„œ 전체 값을 μƒˆλ‘œ μ €μž₯ν•΄μ£Όμ–΄μ•Όλ§Œ κ°’μ˜ 변경이 κ°€λŠ₯ν•˜λ‹€.
    이 경우 μ•„μ˜ˆ μƒˆλ‘œμš΄ 값을 λ‹€μ‹œ ν• λ‹Ήν•˜λŠ” κ²ƒμ΄λ―€λ‘œ λ‹Ήμ—°ν•˜κ²Œλ„ λ©”λͺ¨λ¦¬ μ£Όμ†ŒλŠ” 달라진닀.

πŸ“ mutable 객체와 immutable 객체의 λ³€μˆ˜ λŒ€μž… 비ꡐ - 얕은 볡사

mutableκ³Ό immutable λͺ¨λ‘ κ·Έλƒ₯ λ³€μˆ˜μ— λŒ€μž…ν•  λ•ŒλŠ” '얕은 볡사'λΌλŠ” 것을 ν•˜κ²Œ λœλ‹€.

(μŠ¬λΌμ΄μ‹±λ„ 얕은 볡사, copy λͺ¨λ“ˆμ˜ copy λ©”μ†Œλ“œλ„ 얕은 볡사)

얕은 볡사λ₯Ό ν•˜λ©΄ μ–΄λ–€ 일이 μƒκΈ°λŠ”μ§€ μ•„λž˜ μ½”λ“œμ—μ„œ ν™•μΈν•˜μž.

 

mutable 객체와 immutable 객체에 각각 λ³€μˆ˜λ₯Ό λŒ€μž…ν–ˆμ„ λ•Œμ˜ κ²°κ³Όλ₯Ό μ½”λ“œλ‘œ μž‘μ„±ν–ˆλ‹€.

x1 = [1, 2, 3]
x2 = x1
x2[0] = 0
print(x1, x2) # output : [0, 2, 3] [0, 2, 3]
print(id(x1), id(x2)) # output : 4481772864 4481772864

y1 = "abc"
y2 = y1
y2 = "def"
print(y1, y2) # output : abc def
print(id(y1), id(y2)) # output : 4516896368 4517570352
  • x1에 [1, 2, 3]을 μ €μž₯ν•˜κ³ , x2에 x1을 μ €μž₯ν•΄μ£Όμ—ˆκ³ ,  x2[0]λ₯Ό 0으둜 λ°”κΏ”μ£Όμ—ˆλ‹€.
    이 λ•Œ x1κ³Ό x2에 μ €μž₯된 값을 ν™•μΈν•˜λ©΄ λ‘˜ λ‹€ [0, 2, 3]으둜 같은 것을 μ•Œ 수 μžˆλ‹€.
    μ΄μœ λŠ” 각 리슀트의 μ£Όμ†Œλ₯Ό ν™•μΈν•œ 결과둜 μ•Œ 수 μžˆλŠ”λ°, x1κ³Ό x2λŠ” 같은 μ£Όμ†Œλ₯Ό 가진닀.
  • y1μ—λŠ” "abc" str 값을 ν• λ‹Ήν–ˆκ³ , y2에 y1을 λ„£μ–΄μ£Όμ—ˆλ‹€.
    그리고 μœ„μ—μ„œ λ§ν–ˆλ“―μ΄ immutable κ°μ²΄λŠ” ν•˜λ‚˜ ν•˜λ‚˜μ˜ μš”μ†Œλ₯Ό λ³€ν™˜ν•˜λŠ” 것이 λΆˆκ°€ν•˜λ―€λ‘œ
    y2μ—λŠ” μ•„μ˜ˆ μƒˆλ‘œμš΄ 값을 λ‹€μ‹œ ν• λ‹Ήν•΄μ£Όμ—ˆλ‹€.
    κ·ΈλŸ¬λ‹ˆ λ‹Ήμ—°ν•˜κ²Œλ„ y1, y2λŠ” λ‹€λ₯Έ 값을 가지고, μ£Όμ†Œλ„ λ‹€λ₯Έ 것을 확인할 수 μžˆλ‹€.

πŸ“ κΉŠμ€ 볡사

리슀트 같은 mutable κ°μ²΄λ“€μ—κ²Œ λ‹€λ₯Έ λ©”λͺ¨λ¦¬ μ£Όμ†Œλ₯Ό μ£Όμ†Œ μ‹Άλ‹€λ©΄ κΉŠμ€ 볡사λ₯Ό μ‚¬μš©ν•΄μ£Όλ©΄ λœλ‹€.

κΉŠμ€ λ³΅μ‚¬λŠ” copy λͺ¨λ“ˆμ„ importν•˜κ³ , deepcopy λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

 

import copy

deep_a = [1, 2, 3]
deep_b = copy.deepcopy(deep_a)
print(id(deep_a), id(deep_b)) # output : 4520427392 4520425664
deep_b[0] = 0
print(deep_a, deep_b) # output : [1, 2, 3] [0, 2, 3]
  • [1, 2, 3]을 μ €μž₯ν•œ deep_a 리슀트λ₯Ό deepcopy λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ deep_b에 ν• λ‹Ήν–ˆλ‹€.
    이 경우 idλ₯Ό ν™•μΈν–ˆμ„ λ•Œ, μ„œλ‘œ λ‹€λ₯Έ μ£Όμ†Œλ₯Ό κ°€μ§€λŠ” 것을 μ•Œ 수 μžˆλ‹€.
  • deep_b[0]을 0으둜 λ°”κΏ”μ£Όμ—ˆμ„ λ•Œλ„ μ„œλ‘œ κ°€λ¦¬ν‚€λŠ” μ£Όμ†Œκ°€ λ‹€λ₯΄λ‹ˆ
    λ‹Ήμ—°ν•˜κ²Œλ„ μ„œλ‘œ 영ν–₯을 주지 μ•ŠλŠ” λͺ¨μŠ΅μ„ 확인할 수 μžˆλ‹€.

πŸ– μš”μ•½

mutable 객체(λŒ€ν‘œμ μœΌλ‘œ list)λŠ” κΉŠμ€ 볡사λ₯Ό μ‚¬μš©ν•΄μ£Όμ§€ μ•ŠμœΌλ©΄ λ³€μˆ˜ λŒ€μž… μ‹œ 같은 λ©”λͺ¨λ¦¬ μ£Όμ†Œλ₯Ό κ°€λ¦¬ν‚€κ²Œ λ˜λ―€λ‘œ,
μ™„μ „νžˆ μˆœμˆ˜ν•˜κ²Œ ν• λ‹Ήλœ κ°’λ§Œμ„ λ³΅μ‚¬ν•˜κ³  μ‹Άλ‹€λ©΄ copy λͺ¨λ“ˆμ˜ deepcopy λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•΄μ£Όμ–΄μ•Ό ν•œλ‹€.

λŒ“κΈ€