← notes

Python - Object References, Mutability, Recycling

2024-09-28 · python

[!TIP] Source 전문가를 위한 파이썬(Fluent Python) 6장

변수란 무엇인가

변수는 상자에 붙인 레이블이지 상자 자체가 아니다

a = [1,2,3]
b = a
a.append(4)
b 
# --> [1,2,3,4]
class Gizmo:
	def __init__(self):
		print(f'Gizmo id: {id(self)}')

y = Gizmo()*10
# --> print Gizmo id & Error가 동시 발생

정체성( == 와 is연산자)

charles = {'name': 'Charles L. Dogson', 'born':1832}
lewis = charles

lewis is charles #True

id(lewis)
id(charles)
#---> 동일한 값

alex = {'name': 'Charles L. Dogson', 'born':1832}

alex is charles #False
alex == charles #False

깊은 복사 v.s. 얕은 복사

![[deep-copy-shallow-copy.png|600]]

l1 = [3,[66,55,44],(7,8,9)]
l2 = list(l1) #또는 l2 = l1[:] =======> Shallow Copy

l1.append(100)
#l1: [3,[66,55,44],(7,8,9),100]
#l2: [3,[66,55,44],(7,8,9)] -> 100이 추가되지 않았음

l1[1].remove(55) 
#l1: [3,[66,44],(7,8,9),100]
#l2: [3,[66,44],(7,8,9)] 

l2[2]+=(10,11)
#l1: [3,[66,44],(7,8,9),100]
#l2: [3,[66,44],(7,8,9,10,11)]
class Bus:
	def __init__(self, passengers=None):
		if passengers is None:
			self.passengers = []
		else:
			self.passengers = list(passengers)
	def pick(self,name):
		self.passengers.append(name)
	def drop(self,name)
		self.passengers.remove(name)

import copy

bus1 = Bus(['Alice','Bill','Claire','David'])
bus2 = copy.copy(bus1) #shallow copy
bus3 = copy.deepcopy(bus1) #deep copy

bus1.drop('Bill')
id(bus1.passengers),id(bus2.passengers),id(bus3.passengers)
bus2.passengers

참조로서의 함수 매개변수

가변 매개변수 주의사항

class HauntedBus:
	def __init__(self, passengers=[]):
		self.passengers = passengers
	def pick(self,name):
		self.passengers.append(name)
	def drop(self,name)
		self.passengers.remove(name)

bus1 = HauntedBus(['Alis','Bill'])
bus1.pick('Charlie')
bus1.drop('Alice')
bus1.passengers #Bill, Charlie

bus2 = HauntedBus() #기본값인 빈 리스트로 시작
bus2.pick('Carrie')
bus2.passengers #Carrie

bus3 = HauntedBus() #bus2
bus3.passengers #Carrie

bus2.passengers is bus3.passengers #True
class TwilightBus:
	def __init__(self, passengers=None):
		if passengers is None:
			self.passengers = []
		else:
			self.passengers = passengers 
			#문제 = list(passengers)로 복사하지 않고 그대로 참조하게 함
	def pick(self,name):
		self.passengers.append(name)
	def drop(self,name)
		self.passengers.remove(name)

basketball_team = ['Sue','Tina','Maya','Diana','Pat']
bus = TwilightBus(basketball_team)
bus.drop('Tina')

basketball_team #['Sue','Maya','Diana','Pat']

del과 가비지 컬렉션

Weak reference

import weakref 
class MyClass: 
	def __del__(self): 
	print("MyClass instance is being destroyed") 
	
obj = MyClass()
weak_ref = weakref.ref(obj) 
print(weak_ref()) # 객체에 접근 가능 
del obj #strong reference가 없어지면서 참조 카운트는 0이 됨
print(weak_ref())  # None 반환 (객체는 위에서 없어졌음)
import weakref
s1 = {1,2,3}
s2 = s1
def bye():
	print('...like tears in the rain.')
ender = weakref.finalize(s1,bye) # {1,2,3} 객체에 bye() 콜백 등록

ender.alive #True
del s1
s2 = 'spam'
ender.alive #False