ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python에서 immutable object와 mutable object
    TeX과 친구들 2025. 9. 23. 18:15

    pymupdf 패키지를 이용하여 PDF에서 특정 그래픽 요소를 제거하고 대신 주석을 추가하는 프로그램을 만들었다.

        def removeStrokes(self, inputPDF, outputPDF):

            doc = pymupdf.open(inputPDF)

            for pageNumber in range(doc.page_count):
                page = doc[pageNumber]
                drawings = page.get_drawings()
                for drawing in drawings:
                    if drawing['type'] == 's' and (drawing['color'] == self.GREEN or drawing['color'] == self.ORANGE):
                        rect = drawing['rect']
                        # 바탕 줄 위치 기록하기
                        if drawing['color'] == self.GREEN:
                            if pageNumber in self.GreenPages.keys():
                                self.GreenPages[pageNumber].append(rect)
                            else:
                                self.GreenPages[pageNumber] = [rect]
                        if drawing['color'] == self.ORANGE:
                            if pageNumber in self.OrangePages.keys():
                                self.OrangePages[pageNumber].append(rect)
                            else:
                                self.OrangePages[pageNumber] = [rect]
                        # 바탕 줄 지우기
                        rect[1] = rect[1] - drawing['width']/2
                        rect[3] = rect[3] + drawing['width']/2
                        page.add_redact_annot(rect)
                page.apply_redactions(0,2,1)
            doc.save(outputPDF, garbage=2, deflate=True, clean=True)

    drawing.remove()나 drawing.delete() 같은 것이 있으면 좋으련만, page.add_redact_annot()와 page.apply_redactions()를 함께 사용해서 그래픽 객체를 제거하거나 변경할 수 있다. 덮어쓴다는 것이 더 정확한 설명일 것이다. 방법이 없지 않으니, 왜 이렇게 만들었냐고 저자에게 따질 일은 아니다.

    위 코드에서 doc은 일종의 스트림 객체이다. page와 drawing 역시 객체이다. 내가 처음에 이해하지 못했던 것은 page와 drawing이 어떤 값들의 복사본이 아니라 레퍼런스라는 점이다. 달리 말해, C++의 포인터처럼 작동한다는 것이다. page와 drawing에 가해진 어떤 변경이 doc.save()에 의해 그대로 저장되기 때문에 저것들이 레퍼런스 객체라고 이해할 수 있다.

    그렇다면 어떤 변수가 복사본이고, 어떤 변수가 레퍼런스일까? Python에 immutable (불변) object와 mutable (가변) object가 있다고 한다. integer, string 따위가 immutable이고, list, dictionary, class 따위가 mutable이라고 한다. "a = 1"이라 선언할 때 a가 불변이라니 무슨 말일까? 놀랍게도 a에 어떤 연산을 가할 때, 그것이 가리키는 메모리에서 값이 바뀌어 저장되는 게 아니고, 그 결과가 새로운 메모리에 생긴다고 한다. 객체의 고유 값을 보여주는 id() 함수를 이용해서 immutable 객체와 mutable 객체의 차이를 볼 수 있다.

    참고로, pymupdf.Rect(P(x0,y0), P(x1,y1))에 주어지는 네 좌표 값들은 서로 달라야 한다. (https://pymupdf.readthedocs.io/en/latest/rect.html) 그것은 PDF 사양에 어긋난다기보다 pymupdf 저자가 처리 조건들을 그렇게 만든 것으로 보인다.

    'TeX과 친구들' 카테고리의 다른 글

    XSLT에 대하여  (0) 2025.12.18
    readhanja 루아텍 패키지  (0) 2025.09.01
    VS Code에서 한자 찾기  (0) 2025.08.29
    XSLT로 긴 아이디 만들기  (0) 2025.08.20
    紙榜  (0) 2025.02.12

    댓글

Designed by Tistory.