본문 바로가기
CS/Python&R

알고리즘 인사이드 with 파이썬

by Diligejy 2023. 11. 8.

 

 

 

 

p.43

두 인스턴스가 지닌 좌표의 거리를 계산하여 출력하면 다음과 같습니다.

origin = Coordinate()
target = Coordinate(10, 10)
dist = origin.calc_distance(target)
print(dist)

 

이외에 클래스에 메서드의 접근 제어를 private으로 선언하려면 메서드 이름 앞에 _를 2개 붙이면 됩니다.

 

def __reset(self):
        self.x = 0

 

 

__ 를 앞에 붙인 메서드는 private으로 선언되기 때문에 다음과 같이 호출할 수 없습니다. 따라서 다음과 같은 예외가 발생합니다.

 

origin.__reset()

 

Traceback (most recent call last):

    File "...coordinate.py", line 35, in <module>

        origin.__reset()

AttributeError:  'Coordinate' object has no attribute '__reset'

 

private으로 선언한 메서드는 오직 클래스 메서드에서만 호출할 수 있습니다.

 

p.43~44

 

정적 메서드 static method는 클래스 인스턴스를 생성하지 않고 바로 사용할 수 있는 메서드로, 멤버 속성 등에 접근할 수 없는 순수함수로 사용합니다.

class Printer:
    @staticmethod
    def print_with_line_member(items: List[str]):
        for i in range(len(items)):
            print(f'{i}: {items[i]}')

 

@staticmethod 키워드를 통해 정적 메서드로 데커레이트된 메서드를 정의할 수 있습니다. 이 때 정적 메서드는 self의 키워드를 첫 번째 인수로 설정하지 않습니다. 이후 다음과 같이 인스턴스의 생성 없이 메서드를 호출할 수 있습니다.

 

Printer.print_with_line_number([1, 2, 3, 4, 5])

 

 

p.46~47

파이썬에서 멀티스레딩은 오직 하나의 코어만을 사용합니다. 즉, 여러 코어를 사용해 스레드를 병렬(parallel) 동작하지 않습니다. 오직 병행(concurrent) 처리만 가능합니다. 이러한 제약이 발생하는 원인은 GIL(global interpreter lock)에 있습니다.

 

파이썬의 객체는 여러 스레드에서 병렬로 접근하면 값이 정상적으로 갱신되지 않아 의도하지 않은 값을 갖게 되는 레이스 컨디션(race condition) 문제가 발생합니다. 이를 막기 위해 파이썬은 하나의 스레드만 객체의 값을 갱신할 수 있도록 뮤텍스인 GIL을 동작시킵니다. 따라서 병렬 처리가 불가능하게 되어 H/W가 지닌 코어 수만큼 최대 성능을 발휘할 수 없습니다. 

 

쉽게 말하면, 공유 객체의 레이스 컨디션을 막기 위한 뮤텍스인 GIL 때문에 스레드를 사용할 수는 있으나 하나의 코어로 여러 스레드가 동작하기에는 한계가 있다는 것입니다. 파이썬의 threading 모듈을 사용하면 간단하게 멀티스레딩 코드를 작성할 수 있지만, 코어의 성능을 최대한 발휘하려면 멀티 프로세스 기능을 사용해야 합니다.

 

알고리즘을 효과적으로 구현하려다 보면 여러 개의 스레드를 동작시켜야 할 떄가 있습니다. 시스템의 CPU 자원을 최대한 활용해 처리한다면 여러 스레드를 적절히 제어하여 작업을 수행하고 그 결과를 다른 스레드가 받아서 처리하도록 해야 합니다. 그러나 앞서 설명했듯이 파이썬은 GIL 때문에 하나의 프로세스에 여러 코어로 스레드를 구동하는 것을 지원하지 않습니다. 대신 multiprocess 모듈로 쉽게 멀티 프로세스를 구동할 수 있는 기능을 제공합니다.

 

p.62

장바구니와 스택의 공통점은 2가지입니다. 첫 번째는 스택에 값을 넣고 뺄 때는 먼저 들어간 것이 가장 나중에 나온다는 점입니다. 두 번째는 그 과정이 상당히 번거롭다는 것입니다. 그렇다면 이 번거로운 스택을 사용하는 이유는 무엇일까요?

 

프로그래밍 언어를 학습하면 변수 선언과 변수가 저장되는 위치인 전역 영역, 힙 영역, 스택 영역 등을 배우게 됩니다. 이때 말하는 스택이란 '현재 코드를 실행하는 프로세스 혹은 스레드의 메모리 영역'입니다. 함수에 지역 변수를 선언하면 바로 이 스택 영역에 변수가 저장됩니다.

 

또, 함수를 호출하면 함수가 실행된 다음 다시 원래 위치로 돌아와야 하는데 이 돌아올 위치를 저장하는 데도 스택이 필요합니다. 좀 더 쉽게 말하면 방금 실행한 작업을 되돌리는 실행 취소 단축키인 Ctrl + Z 와 같다고 볼 수 있습니다. 방금 수행한 작업을 스택이라는 자료구조에 저장해 뒀다가 실행된 순서의 반대로 되돌리는 데 사용합니다.

댓글