CS

[Python] 객체 참조, 가변성, 재활용

왕밤빵도라에몽 2025. 3. 30. 14:59
728x90

변수의 개념

변수는 개체에 붙은 레이블이다.
따라서 b = a는 a의 내용물을 b에 복사하는 것이 아니라 이미 a라는 레이블이 붙은 객체에 레이블b를 붙이는 것이다.
객체는 변수가 할당되기 전에 생성된다.
객체는 이름에 바인딩되기 전에 이미 존재해야 한다.

정체성, 동질성, 별칭

>>> charles = {'name': 'Charles L. Dodgson, 'born': 1832}
>>> lewis = charles    # lewis와 charles는 별칭 / 동일한 객체를 가짐
>>> lalex = {'name': 'Charles L. Dodgson, 'born': 1832}   # charles에 할당된 객체가 아닌 그 복사본을 가리킴
>>> alex == charles   # `__eq__()` 구현 방식에 따라서는 두 객체는 같음
True
>>> alex is not charles   # 하지만 두 객체의 정체성이 다름
True
  • 객체의 정체성은 일단 생성된 후에는 절대 변경되지 않는다.
  • 정체성은 메모리 내의 객체 주소라고 생각할 수 있다.
  • is 연산자는 두 객체의 정체성을 비교한다
  • id() 함수는 정체성을 나타내는 정수를 반환한다.

== or is

  • ==(동치 연산자)는 객체의 을 비교
  • is 연산자는 객체의 정체성을 비교

튜플의 상대적 불변성

튜플 자체는 불변형이지만 참조된 항목이 가변형일 수 있다.

>>> t1 = (1, 2, [30, 40])
>>> t2 = (1, 2, [30, 40])
>>> t1 == t2
True
>>> id(t1[-1])
4302515784
>>> t1[-1].append(99)
>>> t1
(1, 2, [30, 40, 99])
>>> id(t1[-1])   # t1[-1]를 변경하였음에도 정체성(메모리 주소)이 동일하다
4302515784
>>> t1 == t2
False   # 하지만 당연히 t1과 t2는 달라졌다.

얕은 복사 / 깊은 복사

자료형 자체의 내장 생성자나 [:] 사용 시 얕은 사본 생성
최상위 컨테이너는 복제하지만, 여전히 동일 객체를 참조

  • copy() 얕은 복사
  • deepcopy() 깊은 복사: 내부 객체까지 모두 새로 복사됨

참조로서의 함수 매개변수

함수 안의 매개변수가 실제 인수의 별칭이 된다.
기본값이 가변 객체일 때 이 객체를 변경하면, 변경 내용이 향후 인스턴스를 생성할 때 영향을 미친다. -> 매개변수로 가변형은 부적합

del과 가비지 컬렉션

  • del(x)이 아니고 del x이다.
  • del은 참조만 제거한다. 객체 제거 X
    CPython에서 객체는 참조 수가 0이 되는 순간 제거된다. 그리고 순환 참조 그룹을 형성해 외부에서 참조할 수 없을 때도 제거된다.
    약한 참조는 참조 수를 증가시키지 않으므로 가비지 컬렉트를 막지 않는다. (약한 참조는 주로 캐시에서 많이 사용. 객체가 더 이상 외부에서 쓰이지 않으면 자동으로 캐시에서 제거됨.)

References

  • 『 전문가를 위한 파이썬(2판) 』, 루시아누 하말류, 한빛미디어, Part 1 - Chapter 6
728x90