μ½”λ“œ - 패캠 μˆ˜μ—… μ½”λ“œ μ°Έκ³  (패캠 μˆ˜μ—… 정리)

 

<이전 κΈ€>

https://silvercoding.tistory.com/26

 

[python 심화] 9. λ³€μˆ˜ λ²”μœ„, Closure, Decorator

μ½”λ“œ - 패캠 μˆ˜μ—… μ½”λ“œ μ°Έκ³  (패캠 μˆ˜μ—… 정리) <이전 κΈ€> https://silvercoding.tistory.com/25 이번 ν¬μŠ€νŠΈμ—μ„œλŠ” λ°μ½”λ ˆμ΄ν„°λ₯Ό μ•Œμ•„λ³Ό 것이닀. λ°μ½”λ ˆμ΄ν„°λŠ” μ–΄λ ΅λ‹€κ³  λŠλΌλŠ” 것이 λ‹Ήμ—°ν•˜λ‹€. λ°μ½”λ ˆμ΄ν„°

silvercoding.tistory.com

 

 

- 얕은 볡사 & is  vs  __eq__ (==) 

x = {'name': 'Kim','age': 33, 'city' : 'Seoul'}
y = x  # ---> 얕은 볡사

μš°μ„  x에 λ”•μ…”λ„ˆλ¦¬λ₯Ό μ €μž₯ν•œλ‹€. κ·Έλ‹€μŒ λ‹¨μˆœν•œ 볡사λ₯Ό ν•œλ‹€. 

print('EX2-1', id(x), id(y))  
print('EX2-2 - ', x == y)
print('EX2-3 - ', x is y)
print('EX2-4 - ', x, y)

 EX2-1 2324412065760 2324412065760 

μš°μ„  id 값을 좜λ ₯ν•΄λ³΄λ‹ˆ 두 값이 μ™„μ „νžˆ κ°™μ•˜λ‹€. 

 EX2-2 -  True 

 EX2-3 -  True 

2-2와 2-3은 μ§κ΄€μ μœΌλ‘œ 봐도 x와 yκ°€ 같은지λ₯Ό λ¬Όμ–΄λ³΄λŠ” μ½”λ“œμΈ 것 κ°™λ‹€. ν•˜μ§€λ§Œ λ‹€λ₯Έ μ’…λ₯˜μ˜ 확인법이닀. __eq__ (==) 와 같은 κ²½μš°λŠ” x와 y의 값이 같은지λ₯Ό ν™•μΈν•˜λŠ” 것이고 , isλŠ” x와 y의 id값이 같은지λ₯Ό ν™•μΈν•˜λŠ” 것이닀. 

 

** 정리 

==(__eq__) : 값을 비ꡐ  vs  is : 객체 μ£Όμ†Œ (정체성) 비ꡐ

 

 EX2-4 -  {'name': 'Kim', 'age': 33, 'city': 'Seoul'} {'name': 'Kim', 'age': 33, 'city': 'Seoul'} 

μœ„ μ˜ˆμ œμ—μ„œλŠ” κ°’, id λͺ¨λ‘ κ°™λ‹€. x와 yλ₯Ό 좜λ ₯ν•˜λ©΄ λ‹Ήμ—°ν•œ 결과둜 같은 λ”•μ…”λ„ˆλ¦¬κ°€ λ‚˜μ˜€λŠ” 것을 λ³Ό 수 μžˆλ‹€. 

 

x의 값을 μˆ˜μ •ν•˜κ±°λ‚˜ μΆ”κ°€ν•˜λ©΄ y도 λ°”λ€”κΉŒ? id값이 κ°™μœΌλ―€λ‘œ λ°”λ€” κ²ƒμœΌλ‘œ μΆ”μ •ν•  수 μžˆλ‹€. 

x['class'] = 10 
print('EX2-5 - ', x, y)

 

 EX2-5 -  {'name': 'Kim', 'age': 33, 'city': 'Seoul', 'class': 10} {'name': 'Kim', 'age': 33, 'city': 'Seoul', 'class': 10} 

x에 값을 μΆ”κ°€ν–ˆλ”λ‹ˆ y도 λ˜‘κ°™μ΄ μΆ”κ°€λ˜λŠ” 것을 μ•Œ 수 μžˆλ‹€. 

 

z = {'name': 'Kim','age': 33, 'city' : 'Seoul', 'class' : 10}

μƒˆ λ”•μ…”λ„ˆλ¦¬ 객체λ₯Ό λ§Œλ“€μ–΄ λ³Έλ‹€. 값은 x와 같도둝! 

print('EX2-6 - ', x, z)
print('EX2-7 - ', x is z)  # 같은 객체냐 
print('EX2-8 - ', x is not z)  
print('EX2-9 - ', x == z)  # 값이 같냐

 EX2-6 -  {'name': 'Kim', 'age': 33, 'city': 'Seoul', 'class': 10} {'name': 'Kim', 'age': 33, 'city': 'Seoul', 'class': 10} 
 EX2-7 -  False 
 EX2-8 -  True 
 EX2-9 -  True 

x와 zλ₯Ό 비ꡐ해 보면 id값은 λ‹€λ₯΄κ³ , κ°’λ§Œ κ°™λ‹€κ³  λ‚˜μ˜€λŠ” 것을 λ³Ό 수 μžˆλ‹€. 이 κ²½μš°μ—λŠ” x의 값을 λ³€κ²½ν•˜μ—¬λ„ z의 값은 λ³€ν•˜μ§€ μ•Šμ„ 것이닀. (λ‹Ήμ—°ν•œ μ†Œλ¦¬) 

 

 

*** cf ) νŠœν”Œ (λΆˆλ³€ν˜•) 비ꡐ 

tuple1 = (10, 15, [100, 1000])
tuple2 = (10, 15, [100, 1000])

print('EX3-1 - ', id(tuple1), id(tuple2))
print('EX3-2 - ', tuple1 is tuple2)
print('EX3-3 - ', tuple1 == tuple2)
print('EX3-4 - ', tuple1.__eq__(tuple2))

 EX3-1 -  2324415315832 2324415315544 
 EX3-2 -  False 
 EX3-3 -  True 
 EX3-4 -  True 

 

 

 

 

- Copy & DeepCopy (얕은 볡사 , κΉŠμ€ 볡사) 

tl1 = [10, [100, 105], (5, 10, 15)]
tl2 = tl1
tl3 = list(tl1)

리슀트 μ•ˆμ— 숫자, 리슀트, νŠœν”Œμ„ 각각 넣은 ν›„, tl2μ—λŠ” 얕은 볡사λ₯Ό , tl3μ—λŠ” list의 μΈμžμ— λ„£μ–΄ μƒˆ 객체λ₯Ό 생성해 μ€€λ‹€. 

print('EX4-1 - ', tl1 == tl2)
print('EX4-2 - ', tl1 is tl2)
print('EX4-3 - ', tl1 == tl3)
print('EX4-4 - ', tl1 is tl3)

 EX4-1 -  True 
 EX4-2 -  True 
 EX4-3 -  True 
 EX4-4 -  False 

4-3κ³Ό 4-4와 같은 κ²½μš°λŠ” 값은 κ°™μ§€λ§Œ, κ°μ²΄λŠ” λ‹€λ₯΄λ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€. 

 

 

tl1.append(1000)
tl1[1].remove(105)

tl1에 1000을 μΆ”κ°€ν•˜κ³ , 1번째 λ¦¬μŠ€νŠΈμ—μ„œ 105λ₯Ό μ œκ±°ν•˜λ©΄ μ–΄λ–»κ²Œ 될까 ! 

print('EX4-5 - ', tl1)
print('EX4-6 - ', tl2)
print('EX4-7 - ', tl3)

 EX4-5 -  [10, [100], (5, 10, 15), 1000] 
 EX4-6 -  [10, [100], (5, 10, 15), 1000] 
 EX4-7 -  [10, [100], (5, 10, 15)] 

tl2λŠ” 같은 객체둜 λ³΅μ‚¬λ˜μ–΄ 있기 λ•Œλ¬Έμ— tl1κ³Ό 같은 것을 λ³Ό 수 μžˆλ‹€. 그런데 tl3λŠ” 반만 λ˜‘κ°™λ‹€! μ™œ 그럴까? 

print(id(tl1[1])) # tl1κ³Ό tl3의 idλŠ” λ‹€λ₯΄μ§€λ§Œ μ•ˆμ— μžˆλŠ” 리슀트의 id값은 κ°™λ‹€. ! 
print(id(tl3[1]))

 2324415643528 
 2324415643528 

μ•„ . tl1κ³Ό tl3 자체 객체의 id값은 λ‹¬λžμ§€λ§Œ, κ·Έ μ•ˆμ— μžˆλŠ” 1번째 리슀트의 id값은 κ°™μ•˜λ‹€. 점점 이 λ°©λ²•μœΌλ‘œ ν•˜λŠ” λ³΅μ‚¬μ˜ ν—ˆμ μ΄ 보이기 μ‹œμž‘ν•œλ‹€. 

 

tl1[1] += [110, 120]
tl1[2] += (110, 120)

tl1의 λ¦¬μŠ€νŠΈμ™€ νŠœν”Œμ— 각각 값을 μΆ”κ°€ν•΄μ€€λ‹€. 

print('EX4-8 - ', tl1)
print('EX4-9 - ', tl2) # νŠœν”Œ 재 ν• λ‹Ή (깩체 μƒˆλ‘œ 생성) ---> 데이터가 ν˜„μ €νžˆ λ§Žμ„ λ–ˆ 주의 ν•΄μ•Ό ν•œλ‹€. 객체λ₯Ό μƒˆλ‘œ μƒμ„±ν•œλ‹€λŠ” 것은 데이터 손싀이 μžˆμ„ μˆ˜λ„ 있고 , λ©”λͺ¨λ¦¬λ₯Ό 더 차지할 μˆ˜λ„ 있게 되기 λ•Œλ¬Έ !
print('EX4-10 - ', tl3)

 EX4-8 -  [10, [100, 110, 120], (5, 10, 15, 110, 120), 1000] 
 EX4-9 -  [10, [100, 110, 120], (5, 10, 15, 110, 120), 1000] 
 EX4-10 -  [10, [100, 110, 120], (5, 10, 15)] 

μš°μ„  tl1, tl2λŠ” μ—¬κΈ°μ„œλ„ λ˜‘κ°™μ΄ 움직인 λ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€. 그런데 tl3μ—μ„œλŠ” 쑰금 μ΄μƒν•œ ν˜„μƒμ΄ 일어났닀. λ¦¬μŠ€νŠΈλŠ” 값이 μΆ”κ°€λ˜μ—ˆμ§€λ§Œ , νŠœν”Œμ€ 값이 μΆ”κ°€λ˜μ§€ μ•Šμ•˜λ‹€. 닡은 μ½”λ“œ 주석에 μ¨μžˆλ“―μ΄, νŠœν”Œμ€ 객체λ₯Ό μƒˆλ‘œ μƒμ„±ν•˜μ—¬ 재 할당이 되기 λ•Œλ¬ΈμΈλ°, 이해λ₯Ό μœ„ν•˜μ—¬ id값을 좜λ ₯ν•΄λ³΄μ•˜λ‹€. 

 

# 리슀트, νŠœν”Œμ— κ°’ μΆ”κ°€ μ „ 
print(id(tl1[2]))
print(id(tl2[2]))
print(id(tl3[2]))

...

# 리슀트, νŠœν”Œμ— κ°’ μΆ”κ°€ ν›„
print(id(tl1[2]))
print(id(tl2[2]))
print(id(tl3[2]))

 1367137568664 
 1367137568664 
 1367137568664 

 

 1367137218056 
 1367137218056 
 1367137568664 

리슀트처럼 tl1, tl3의 νŠœν”Œ id값은 κ°™μ•˜λ‹€. νŠœν”Œμ—μ„  이게 μ΄μŠˆκ°€ λ˜λŠ” 것이닀! tl1[2] += (110, 120) <--- 이 μ½”λ“œκ°€ μ‹€ν–‰λ˜λ©΄ νŠœν”Œμ΄ μž¬ν• λ‹Ήλ˜μ–΄ μƒˆ 객체가 μƒμ„±λœλ‹€. κ·Έλž˜μ„œ id값을 보면 이 μ½”λ“œ μ „κ³Ό ν›„μ˜ tl1, tl2 id값이 달라진 것을 λ³Ό 수 μžˆλ‹€. κ·Έλž˜μ„œ μ „κ³Ό 같은 id값을 가진 tl3의 νŠœν”Œμ€ λ³€ν™”ν•˜μ§€ μ•ŠλŠ” 것이닀. 

 

 

 

 

*** copy & Deep copy (κΉŠμ€ 볡사) μ‹€μŠ΅ν•΄λ³΄κΈ° 

(ex) μž₯λ°”κ΅¬λ‹ˆ 클래슀 

class Basket:
    def __init__(self, products=None):
        if products is None:
            self._products = []
        else:
            self._products = list(products)  # μƒˆλ‘œμš΄ 객체 생성

    def put_prod(self, prod_name):
        self._products.append(prod_name)

    def del_prod(self, prod_name):
        self._products.remove(prod_name)

_products에 물건을 λ‹΄κ³ , put_prod λ©”μ†Œλ“œλ‘œ 물건 μΆ”κ°€ , del_prod λ©”μ†Œλ“œλ‘œ 물건 μ‚­μ œλ₯Ό ν•˜λŠ” 클래슀 생성! 

import copy

basket1 = Basket(['Apple', 'Bag', 'TV', 'Snack', 'Water'])
basket2 = copy.copy(basket1)  # 얕은 볡사 
basket3 = copy.deepcopy(basket1)  # κΉŠμ€ 볡사 ---> 객체 μ•ˆμ— μžˆλŠ” μΈμŠ€ν„΄μŠ€ λ³€μˆ˜κΉŒμ§€ μ°Έμ‘°

copyλ₯Ό importν•˜μ—¬ 얕은 볡사(copy.copy) 와 κΉŠμ€ 볡사(copy.deepcopy) λ₯Ό ν•΄λ³Έλ‹€. 

print('EX5-1 - ', id(basket1), id(basket2), id(basket3))
print('EX5-2 - ', id(basket1._products), id(basket2._products), id(basket3._products))

 EX5-1 -  1367137770520 1367137770464 1367137771304 
 EX5-2 -  1367137799240 1367137799240 1367137626888 

copyλ₯Ό μ‚¬μš©ν•˜λ©΄ 객체 μžμ²΄λŠ” λͺ¨λ‘ λ‹€λ₯΄κ²Œ λ‚˜μ˜€λŠ” 것을 λ³Ό 수 μžˆλ‹€. EX5-2μ—μ„œ 얕은 볡사와 κΉŠμ€λ³΅μ‚¬μ˜ 차이점이 보인닀. deepcopyλŠ” 객체 μ•ˆμ— μžˆλŠ” μΈμŠ€ν„΄μŠ€ λ³€μˆ˜κΉŒμ§€ μ°Έμ‘°λ₯Ό ν•˜κΈ° λ•Œλ¬Έμ— λ³€μˆ˜μ˜ κ°μ²΄κΉŒμ§€ id의 값이 λ‹€λ₯΄λ‹€! 

 

basket1.put_prod('Orange')
basket2.del_prod('Snack')

basket1에 Orangeλ₯Ό λ„£κ³ , Snack을 μ‚­μ œν•˜λ©΄ μ–΄λ–»κ²Œ λ³€ν•˜λŠ”μ§€ 확인해 보자! 

# λΉ…λ°μ΄ν„°λ‚˜, μ›Ήκ°œλ°œν•  λ–„ μ£Όμ˜ν•΄μ•Ό ν•œλ‹€. 
print('EX5-3 - ', basket1._products)
print('EX5-4 - ', basket2._products)  
print('EX5-5 - ', basket3._products)

 EX5-3 -  ['Apple', 'Bag', 'TV', 'Water', 'Orange'] 
 EX5-4 -  ['Apple', 'Bag', 'TV', 'Water', 'Orange'] 
 EX5-5 -  ['Apple', 'Bag', 'TV', 'Snack', 'Water'] 

μ΄λ ‡κ²Œ basket1κ³Ό basket2λŠ” μ„œλ‘œ 영ν–₯을 λ°›λŠ”λ‹€. κΉŠμ€λ³΅μ‚¬λ₯Ό ν•œ basket3λŠ” 영ν–₯을 받지 μ•ŠλŠ”λ‹€. 

μ΄λŠ” 빅데이터 λ˜λŠ” μ›Ήκ°œλ°œμ„ ν•  λ•Œ μ£Όμ˜ν•΄μ•Ό ν•œλ‹€. 예λ₯Ό λ“€μ–΄ 빅데이터 뢄석을 ν•  λ•Œ 원본은 μ†μƒμ‹œν‚€μ§€ μ•Šκ³  볡사λ₯Ό ν•˜μ—¬ μ „μ²˜λ¦¬λ₯Ό ν•  경우 얕은 볡사λ₯Ό ν•˜κ²Œ 되면 μƒκ°λ§Œ 해도 μ•„μ°”ν•˜λ‹€. 

 

 

 

- ν•¨μˆ˜ λ§€κ°œλ³€μˆ˜ 전달 주의 

def mul(x, y):
    x += y
    return x

x에 yλ₯Ό λ”ν•΄μ„œ x에 λ„£κ³ , xλ₯Ό returnν•΄μ£ΌλŠ” mul ν•¨μˆ˜ 생성 

x = 10 
y = 5

print('EX6-1 - ', mul(x, y), x, y)

 EX6-1 -  15 10 5 

ν•¨μˆ˜ μ•ˆμ˜ xκ°€ 15라고 ν•΄μ„œ μ „μ—­λ³€μˆ˜ x의 값이 λ³€κ²½λ˜μ§€λŠ” μ•ŠλŠ”λ‹€. 

 

 

* κ°€λ³€ν˜• a -> 원본 데이터 λ³€κ²½/ ν•¨μˆ˜μ— 전달할 λ•Œ μ›λ³Έμ˜ μ£Όμ†ŒκΉŒμ§€ λ„˜κΉ€

a = [10, 100]
b = [5, 10]

print('Ex6-2 - ', mul(a, b), a, b)  # ---> ν™•μž₯! ! ! ! !

 Ex6-2 -  [10, 100, 5, 10] [10, 100, 5, 10] [5, 10] 

ν•˜μ§€λ§Œ κ°€λ³€ν˜•μΈ 리슀트 νƒ€μž…μ˜ aλ₯Ό mul에 λ„£μœΌλ©΄ μ „μ—­λ³€μˆ˜μΈ a의 κ°’κΉŒμ§€ 변해버린닀. 즉 원본데이터가 λ³€κ²½λ˜λŠ” 것이닀. ν•¨μˆ˜μ— 이 데이터λ₯Ό 전달할 λ•Œ μ›λ³Έμ˜ μ£Όμ†ŒκΉŒμ§€ λ„˜κΈ°κΈ° λ•Œλ¬Έμ΄λ‹€. 

 

 

* λΆˆλ³€ν˜• c ---> 원본 데이터 λ³€κ²½ μ•ˆλ¨

c = (10, 100)
d = (5, 10)
print('Ex6-2 - ', mul(c, d), c, d)

λΆˆλ³€ν˜•μΈ νŠœν”Œνƒ€μž…μ˜ c같은 κ²½μš°μ—λŠ” 원본 λ°μ΄ν„°μ˜ 변경이 λ˜μ§€ μ•ŠλŠ”λ‹€. μœ„μ—μ„œ 배웠듯이 νŠœν”Œμ˜ λ‚΄μš©μ΄ 갱신될 λ•ŒλŠ” μƒˆλ‘œμš΄ μ£Όμ†Œμ— 할당이 되기 λ•Œλ¬Έμ΄λ‹€. 

 

 

 

 

- 파이썬 λΆˆλ³€ν˜• μ˜ˆμ™Έ 

: str, bytes, frozenset, Tuple ---> 사본 생성 X ---> μ°Έμ‘° λ°˜ν™˜ (같은 값이면 id 도 κ°™λ‹€) 

tt1 = (1, 2, 3, 4, 5)
tt2 = tuple(tt1)
tt3 = tt1[:]

μ΄λ²ˆμ—” νŠœν”Œμ„ 각각 λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ λ³΅μ‚¬ν•˜μ—¬ tt2와 tt3λ₯Ό μƒμ„±ν•˜μ˜€λ‹€. 

print('EX7-1 - ', tt1 is tt2, id(tt1), id(tt2))
print('EX7-2 - ', tt1 is tt3, id(tt1), id(tt3))

 EX7-1 -  True 1367134857000 1367134857000 
 EX7-2 -  True 1367134857000 1367134857000 

λ¦¬μŠ€νŠΈλŠ” μœ„μ™€ 같은 λ°©λ²•μœΌλ‘œ 객체λ₯Ό μƒμ„±ν•˜λ©΄ μƒˆλ‘œμš΄ μ£Όμ†Œκ°€ λΆ€μ—¬λμ—ˆλ‹€. νŠœν”Œμ€ λΆˆλ³€ν˜•μ΄λ―€λ‘œ 같은 값이면 idλŠ” κ°™λ‹€. λ”°λΌμ„œ λͺ¨λ“  id값이 κ°™κ²Œ λ‚˜μ™”λ‹€. νŠœν”Œμ€ λΆˆλ³€ν˜•μ΄κΈ° λ•Œλ¬Έμ— νŠœν”Œμ— νŠœν”Œμ„ 더할 λ•Œ κΈ°μ‘΄ νŠœν”Œμ— 값이 μΆ”κ°€λ˜λŠ” κ°œλ…μ΄κΈ° λ³΄λ‹€λŠ” μƒˆλ‘œμš΄ νŠœν”Œ 객체가 λ§Œλ“€μ–΄μ§€λŠ” 것이라고 보면 λœλ‹€.  

 

tt4 = (10, 20, 30, 40, 50)
tt5 = (10, 20, 30, 40, 50)
ss1 = 'Apple'
ss2 = 'Apple'

νŠœν”Œκ³Ό λ˜λ‹€λ₯Έ λΆˆλ³€ν˜• str둜 검증을 해보고 λ§ˆμΉœλ‹€. 

print('EX7-3 - ', tt4 is tt5, tt4 == tt5, id(tt4), id(tt5))
print('EX7-4 - ', ss1 is ss2, ss1 == ss2, id(ss1), id(ss2))

 EX7-3 -  True True 1367137216648 1367137216648 
 EX7-4 -  True True 1367137769320 1367137769320 

값이 κ°™μœΌλ©΄ λ‹€λ₯Έ λ³€μˆ˜μ— λ”°λ‘œ 생성을 해도 같은 μ£Όμ†Œλ₯Ό κ°–κ³  μžˆλ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€. 

+ Recent posts