[python] 동적 / 정적 메모리 할당

About_work·2024년 7월 23일
0

python 기초

목록 보기
62/65
  • Python에는 C나 C++ 같은 언어에서 사용하는 것과 같은 직접적인 정적 변수 개념은 없습니다.
  • 하지만 Python에서는 함수나 메서드 내에서 변수를 선언하여, 해당 함수나 메서드가 호출될 때마다 값을 유지하는 방식으로 정적 변수처럼 동작할 수 있습니다.
  • 이를 구현하는 방법에는 몇 가지가 있으며, 가장 일반적인 방법은 함수 속성 또는 클래스 변수를 사용하는 것입니다.

함수 속성 사용

  • 함수 속성을 사용하면 함수에 직접 속성을 추가하여 정적 변수처럼 사용할 수 있습니다.
def func():
    if not hasattr(func, "counter"):
        func.counter = 0  # 초기화
    func.counter += 1
    print("Counter:", func.counter)

# 함수 호출
func()
func()
func()
  • 이 예시에서 func.counter는 함수 속성으로 사용되어, 함수 호출 시마다 값을 유지합니다.

클래스 변수 사용

  • 클래스 변수를 사용하면 클래스의 모든 인스턴스에서 공유되는 변수를 정의할 수 있습니다.
  • 이는 정적 변수의 역할을 할 수 있습니다.
class MyClass:
    counter = 0  # 클래스 변수

    def increment(self):
        MyClass.counter += 1
        print("Counter:", MyClass.counter)

# 인스턴스 생성 및 메서드 호출
obj1 = MyClass()
obj2 = MyClass()

obj1.increment()
obj2.increment()
obj1.increment()
  • 이 예시에서 MyClass.counter는 클래스 변수로 사용되어, 모든 인스턴스가 공유하는 값을 유지합니다.

파이썬에서의 정적 변수와 상태 유지

Python에서 함수 내 상태를 유지하기 위한 몇 가지 다른 방법들도 있습니다. 예를 들어, 클로저(closure)를 사용할 수도 있습니다.

def make_counter():
    count = 0
    
    def counter():
        nonlocal count
        count += 1
        return count
    
    return counter

counter = make_counter()

print(counter())
print(counter())
print(counter())

이 예시에서 count 변수는 make_counter 함수가 호출될 때마다 상태를 유지하여 정적 변수처럼 동작합니다.

결론

  • Python에는 C나 C++과 같은 직접적인 정적 변수 개념은 없지만,
    • 함수 속성, 클래스 변수, 클로저 등을 사용하여 유사한 기능을 구현할 수 있습니다.
  • 함수 속성은
    • 함수에 직접 속성을 추가하여 상태를 유지하는 방식입니다.
  • 클래스 변수는
    • 클래스의 모든 인스턴스에서 공유되는 변수를 정의하는 방식입니다.
  • 클로저는
    • 함수 내 상태를 유지하는 또 다른 유용한 방법입니다.

Python에서 변수는 메모리에 저장되는 방식에 따라 동적 메모리 할당과 정적 메모리 할당으로 구분할 수 있습니다. 그러나, Python의 변수는 대부분 동적 메모리 할당을 사용합니다. 그럼에도 불구하고, 변수의 용도와 특징에 따라 어떻게 메모리가 할당되는지 이해할 필요가 있습니다.

동적 메모리 할당이 필요한 변수의 종류

동적 메모리 할당은 프로그램 실행 중에 메모리 크기가 결정되는 변수들에 대해 사용됩니다. 이는 Python의 대부분의 변수에 해당합니다. Python은 내부적으로 동적 메모리 할당을 통해 변수의 크기와 타입을 관리합니다. 주요 변수 유형은 다음과 같습니다:

  1. 리스트 (List)

    • 크기가 가변적이며, 실행 중에 요소를 추가하거나 제거할 수 있습니다.
    • 예: my_list = [1, 2, 3]
  2. 딕셔너리 (Dictionary)

    • 키-값 쌍으로 이루어져 있으며, 실행 중에 항목을 추가하거나 제거할 수 있습니다.
    • 예: my_dict = {'key1': 'value1', 'key2': 'value2'}
  3. 집합 (Set)

    • 유일한 요소의 집합으로, 실행 중에 요소를 추가하거나 제거할 수 있습니다.
    • 예: my_set = {1, 2, 3}
  4. 클래스 인스턴스 (Instance of Class)

    • 사용자 정의 객체로, 속성과 메서드를 포함할 수 있습니다. 인스턴스 생성 시마다 메모리가 동적으로 할당됩니다.

    • 예:

      class MyClass:
          def __init__(self, value):
              self.value = value
      
      obj = MyClass(10)
  5. 제너레이터 (Generator)

    • 필요한 시점에 값을 생성하므로, 메모리를 효율적으로 사용할 수 있습니다.
    • 예:
      def my_generator():
          yield 1
          yield 2
          yield 3

정적 메모리 할당으로 충분한 변수의 종류

Python에서 대부분의 변수는 동적 메모리 할당을 통해 관리되지만, 일부 변수는 사실상 정적으로 할당된다고 볼 수 있습니다. 이는 주로 단순한 상수와 불변(immutable) 객체에 해당합니다:

  1. 불변 객체 (Immutable Objects)

    • 정수 (Integer)

      • 변경할 수 없는 값으로, Python은 작은 정수 객체를 캐싱하여 메모리를 절약합니다.
      • 예: x = 10
    • 문자열 (String)

      • 불변 객체로, 문자열이 생성되면 변경할 수 없습니다. 새로운 문자열을 생성할 때마다 새로운 메모리가 할당됩니다.
      • 예: name = "John"
    • 튜플 (Tuple)

      • 불변 리스트와 유사한 자료형으로, 요소를 변경할 수 없습니다.
      • 예: my_tuple = (1, 2, 3)
    • 불변 집합 (Frozenset)

      • 요소를 변경할 수 없는 집합입니다.
      • 예: my_frozenset = frozenset([1, 2, 3])
  2. 상수 (Constant)

    • 프로그램 실행 동안 변경되지 않는 값으로 사용됩니다. Python에는 엄격한 상수 개념은 없지만, 변수 이름을 대문자로 작성하여 상수임을 암시할 수 있습니다.
    • 예: PI = 3.14159

정적 vs 동적 메모리 할당 요약

  • 정적 메모리 할당:

    • 프로그램이 시작될 때 메모리가 할당되며, 실행 중에는 변경되지 않습니다.
    • 불변 객체와 상수가 해당합니다.
    • 메모리 크기가 고정적입니다.
    • 예: 정수, 문자열, 튜플, 상수
  • 동적 메모리 할당:

    • 프로그램 실행 중에 필요에 따라 메모리가 할당되고 해제됩니다.
    • 크기와 내용이 변할 수 있는 객체가 해당합니다.
    • 메모리 크기가 가변적입니다.
    • 예: 리스트, 딕셔너리, 클래스 인스턴스, 제너레이터

Python의 동적 메모리 할당은 매우 유연하고 사용하기 쉬워서, 대부분의 경우에 유용합니다. 그러나 메모리 사용량을 최적화하고 성능을 향상시키기 위해 변수의 특성에 맞게 메모리 할당 방식을 이해하고 활용하는 것이 중요합니다.

profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글