티스토리 뷰

11.6. 약한 참조

  • 파이썬은 자동 메모리 관리를 수행한다.

  • 여기서 자동 메모리 관리란 대부분 객체에 대한 참조 횟수 추적 및 순환을 제거하기 위한 가비지 콜렉션을 말한다.

  • 다음과 같이 변수에 그냥 값을 바로 대입하면 참조가 늘어나는 것을 확인할 수 있다.

    import sys
    sys.getrefcount(1)        # 580
    va = 1
    sys.getrefcount(1)        # 581
    del va
    sys.getrefcount(1)        # 580
  • weakref 모듈을 사용하게 되면 약한 참조를 통해 참조 값은 늘어나지 않고 값만 들어간 것을 확인할 수 있다. 참조된 객체를 삭제(del)하게 되면 참조한 값도 사라지는 것을 확인할 수 있다.

    class A:
        def __init__(self, value):
            self.value = value
        def __repr__(self):
            return str(self.value)
    
    a = A(10)                            # 참조를 생성한다
    d = weakref.WearkRefDictionary()
    d['primary'] = a                    # 참조는 생성하지 않는다
    d['primary']                        # 10 (값이 있는 경우만 출려됨)
    del a                                # 참조를 삭제한다
    gc.collect()                        # 0 (가비지콜렉션을 바로 실행한다)
    d['primary']                        # 자동으로 삭제됨
    """Taceback (most recent call last)
      File "<stdin>", line 1, in <module>
        d['primary']
       File "C:\ProgramData\Anaconda3\lib\weakref.py", line 137, in __getitem__
         o = self.data[key]()
     KeyError: 'primary'
     """

11.7. 리스트 작업 도구

  • 내장 리스트 형으로 많은 데이터 구조 요구를 충족시킬 수 있다. 그러나 떄로는 다른 성능 상충 관계가 있는 대안적 구현이 필요할 수도 있다.

  • array 모듈은 array() 객체를 제공한다. 이 객체는 같은 타입의 데이터만을 저장하고 보다 조밀하게 저장하는 리스트와 같다.

  • 다음 예제는 파이썬 int 객체의 일반 리스트의 경우처럼 항목당 16바이트를 사용하는 대신에 , 2바이트의 부호 없는 이진 숫자 (타입 코드 "H")로 저장된 숫자 배열을 보여준다.

    from array import array
    a = array('H', [40, "1"])            # 다른 타입이라 에러
    """Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
    TypeError: an integer is required (got type str)"""
    a = array('H', [4000, 10, 700, 22222])
    sum(a)            #26932
    a[1:3]            # array('H', [10, 700])
  • collections 모듈은 데큐(deque()) 객체를 제공한다. 이 객체는 왼쪽에서 더 빠르게 push/pop 하지만 중간에서의 조회는 더 느려진 리스트와 같다.

    from collections import deque
    d = deque(["task1", "task2", "task3"])
    d.append("task4")
    print("Handling", d.popleft())        # Handling task1
  • 이 객체는 대기열 및 너비 우선 탐색(BFS)를 구현하는데 적합하다.

    unsearched = deque([starting_node])
    def breadth_first_search(unsearched):
        node = unserched.popleft()
        for m in gen_moves(node):
            if is_goal(m):
                return m
            unsearched.append(m)
  • 대안적 리스트 구현 외에도 라이브러리는 정렬된 리스트를 조작하는 함수들이 있는 bisect 모듈과 같은 다른 도구를 제공한다.

    import bisect
    scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')]
    bisect.insort(scores, (300, 'ruby'))
    scores
    # [(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]
  • heapq 모듈은 일반 리스트를 기반으로 힙을 구현하는 함수를 제공한다.

  • 가장 값이 작은 항목은 항상 위치 0에 유지도니다. 가장 작은 요소에 반복적으로 액세스하지만, 전체 목록 정렬을 실행하지 않으려는 경우에 유용하다.

    from heapq import heapify, heappop, heappush
    data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
    heapify(data)                    # 리스트를 힙 순서대로 바꾼다
    hearppush(data, -5)                 # 힙에 새로운 원소를 넣는다
    [heappop(data) for i in range(3)] # 가장 작은 원소 세 개를 리스트로 출력
    # [-5, 0, 1]

11.8. 10진 부동 소수점 산술

  • decimal 모듈은 10진 부동 소수점 산술을 위한 Decimal 데이터형을 제공한다. 내장 float 이진 부동 소수점 구현과 비교할 때, 클래스는 특히 다음과 같은 것들에 유용하다.

    • 정확한 10진수 표현이 필요한 금융 응용 및 기타 용도
    • 정밀도 제어
    • 법적 또는 규제 요구 사항을 충족하는 반올림 제어
    • 유효숫자 추적
  • Decimal()에 인수를 넣을 때 숫자가 아니라 문자로 넣는 것에 유의하자

  • 예를 들어 70센트 전화 요금에 대해 5% 세금을 계산하면, 십진 부동 소수점 및 이진 부동 소수점에 다른 결과가 나온다. 결과를 가장 가까운 센트로 반올림하면 차이가 드러난다.

    from dcimal import *
    round(Decimal('0.70') * Decimal('1.05'), 2)        # Decimal('0.74')
    round(.70 * 1.05, 2)                # 0.73, 2진 부동소수점 때문에 결과가 틀림
  • Decimal 결과 끝에 붙는 0을 유지하며, 두 개의 유효 숫자를 가진 피승수로부터 네 자리 유효 숫자를 자동으루 추론한다.

  • 이진 부동 소수점이 십진수를 정확하게 표현할 수 없을 때 발생할 수 있는 문제를 피한다.

  • 정확한 표현은 Decimal 클래스가 이진 부동 소수점에 적합하지 않응 modulo 계산(%)과 동등성 검사(==)를 수행할 수 있도록 한다.

    Decimal('1.00') % Decimal('0.10')        # Decimal('0.00')
    1.00 % 0.10                              # 0.09999999999999995
    
    sum([Decimal('0.1')]*10) == Decimal('1.0')    # True
    sum([0.1]*10) == 1.0                      # False
  • decimal 모듈은 필요한 만큼의 정밀도로 산술을 제공한다.

    getcontext().prec = 36
    Decimal(1) / Decimal(7)
    # Decimal('0.142857142857142857142857142857142857')


Reference: 파이썬 자습서

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함