Python - 1. 자료형과 변수

2025. 1. 19. 18:13프로그래밍 언어/Python

변수와 자료형은 프로그래밍의 가장 기본적인 요소로, 데이터를 저장하고 처리하는 데 필수적입니다. 이번 섹션에서는 변수 선언, 다양한 자료형, 데이터 변환, 변수의 범위와 특성, 그리고 메모리 관리에 대해 알아본다.


1.1 변수의 선언과 할당

변수는 데이터를 저장하는 이름표 역할을 합니다. Python에서는 변수를 선언할 때 자료형을 명시하지 않고, 값을 할당하면 자동으로 자료형이 결정.

# 변수 선언과 할당 예제
name = "Alice"  # 문자열
age = 25          # 정수
height = 5.6      # 실수
is_student = True # 불리언

실행 결과:

변수 name: Alice
변수 age: 25
변수 height: 5.6
변수 is_student: True

Note: 변수 이름은 문자, 숫자, 밑줄(_)로 구성할 수 있으며, 숫자로 시작할 수 없습니다. 또한, Python의 예약어는 변수 이름으로 사용할 수 없습니다.

Python 예약어 예시: if, else, while, return, import, def


1.2 기본 자료형 (int, float, str, bool)

Python에서 자주 사용되는 기본 자료형은 다음과 같습니다:

  • 정수형(int): 정수값을 저장합니다.
num = 10
print(num)
  • 실행 결과:
10

 

  • 실수형(float): 소수점이 있는 숫자를 저장합니다. 실수형은 무한 소수 및 매우 큰 숫자도 표현할 수 있습니다.
pi = 3.14
large_float = 1.79e308  # 지수 표기법
print(pi, large_float)
  • 실행 결과:
3.14 1.79e+308
  • 문자열(str): 텍스트 데이터를 저장합니다. 작은따옴표(')나 큰따옴표(")로 묶어서 표현합니다.
greeting = "Hello, World!"
print(greeting)
  • 실행 결과:
Hello, World!
  • 불리언(bool): 참(True)과 거짓(False) 값을 나타냅니다.
is_open = False
print(is_open)

# bool()을 사용한 형 변환
print(bool(0))     # False
print(bool(123))   # True
print(bool(""))   # False
print(bool("abc"))# True
  • 실행 결과:
False
False
True
False
True

1.3 자료형 확인 (type 함수)

type 함수를 사용하면 변수의 자료형을 확인할 수 있습니다.

x = 42
print(type(x))

name = "Python"
print(type(name))

실행 결과:

<class 'int'>
<class 'str'>

1.4 데이터 타입 변환 (형 변환)

데이터를 다른 자료형으로 변환할 때는 Python에서 제공하는 형 변환 함수를 사용합니다.

  • 정수로 변환: int()
  • 실수로 변환: float()
  • 문자열로 변환: str()
  • 불리언으로 변환: bool()
# 기본 형 변환 예제
num_str = "123"
num = int(num_str)  # 문자열을 정수로 변환
print(num)

# 다양한 형 변환 예제
try:
    invalid_num = int("abc")  # 잘못된 형 변환 시도
except ValueError as e:
    print(f"형변환 오류: {e}")

float_num = float(num)  # 정수 → 실수
str_num = str(float_num)  # 실수 → 문자열
print(f"실수형: {float_num}, 문자열형: {str_num}")

실행 결과:

123
형변환 오류: invalid literal for int() with base 10: 'abc'
실수형: 123.0, 문자열형: 123.0

Tip: 변환하려는 데이터가 적합하지 않으면 오류가 발생하므로 주의해야 합니다.


1.5 변수의 스코프와 네임스페이스

변수의 스코프(Scope)는 변수가 유효한 코드 범위를 의미하며, 네임스페이스(Namespace)는 변수 이름과 값이 저장되는 공간입니다. Python에서 변수의 스코프는 다음과 같은 LEGB 규칙을 따릅니다:

  1. Local (지역 범위): 함수 내부에서 선언된 변수.
  2. Enclosing (비지역 범위): 중첩 함수의 외부 함수에서 선언된 변수.
  3. Global (전역 범위): 모듈 수준에서 선언된 변수.
  4. Built-in (내장 범위): Python에서 제공하는 기본 네임스페이스.
x = 10  # Global 변수

def outer():
    y = 20  # Enclosing 변수
    def inner():
        z = 30  # Local 변수
        print(f"Global: {x}, Enclosing: {y}, Local: {z}")
    inner()

outer()

실행 결과:

Global: 10, Enclosing: 20, Local: 30  # 각각의 스코프에서 변수 접근

Note: 변수는 가장 가까운 스코프에서부터 검색되며, 상위 범위로 올라갑니다.


1.6 불변성과 가변성의 개념

Python의 자료형은 불변(Immutable) 또는 가변(Mutable) 속성을 가집니다.

  • 불변형(Immutable): 변경이 불가능한 자료형 (e.g., int, float, str, tuple).
  • 가변형(Mutable): 변경이 가능한 자료형 (e.g., list, dict, set).
# 불변형 예제
x = "hello"
id_before = id(x)  # 객체의 메모리 주소 확인
x = x + " world"  # 새 문자열 생성
id_after = id(x)  # 새로운 메모리 주소 할당
print(f"이전 주소: {id_before}, 이후 주소: {id_after}")

# 가변형 예제
lst = [1, 2, 3]
lst.append(4)  # 기존 리스트 수정
print(lst)

# 기본적인 가변/불변 객체 구분
immutable_obj = (1, 2, 3)  # 튜플
mutable_obj = [1, 2, 3]    # 리스트
print(f"불변 객체: {immutable_obj}, 가변 객체: {mutable_obj}")

실행 결과:

이전 주소: 140493572763376, 이후 주소: 140493572764848
[1, 2, 3, 4]
불변 객체: (1, 2, 3), 가변 객체: [1, 2, 3]

1.7 참조와 복사의 차이

Python에서 변수는 값이 아니라 객체에 대한 참조를 저장합니다. 따라서 변수 간 대입은 객체 참조를 공유합니다. 복사에는 다음 두 가지 방식이 있습니다:

  • 얕은 복사(Shallow Copy): 객체의 참조를 복사.
  • 깊은 복사(Deep Copy): 객체 자체와 하위 객체까지 모두 복사.
import copy

# 얕은 복사
lst1 = [1, 2, [3, 4]]
lst2 = lst1.copy()
lst2[2][0] = 100
print("얕은 복사:", lst1, lst2)

# 깊은 복사
lst3 = copy.deepcopy(lst1)
lst3[2][0] = 200
print("깊은 복사:", lst1, lst3)

# list() 생성자를 통한 복사
lst4 = list(lst1)
lst4.append(5)
print("list() 복사:", lst1, lst4)

실행 결과:

얕은 복사: [1, 2, [100, 4]] [1, 2, [100, 4]]
깊은 복사: [1, 2, [100, 4]] [1, 2, [200, 4]]
list() 복사: [1, 2, [100, 4]] [1, 2, [100, 4], 5]

1.8 메모리 관리와 가비지 컬렉션

Python은 가비지 컬렉션(Garbage Collection)을 통해 사용하지 않는 메모리를 자동으로 관리합니다. 이는 참조 카운트(reference count)와 순환 참조 탐지 메커니즘을 기반으로 동작합니다.

  • 참조 카운트: 객체를 참조하는 변수의 수를 관리.
  • 순환 참조 탐지: 참조 카운트가 0이 아니더라도 객체들이 서로를 참조하는 경우를 감지하여 메모리를 해제.
import gc

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

a = Node(1)
b = Node(2)
a.next = b
b.next = a  # 순환 참조

del a
print("순환 참조 해제 전:", gc.collect())  # 가비지 컬렉션 실행

실행 결과:

순환 참조 해제 전: 0  # 환경에 따라 다를 수 있음

Tip: 일반적으로 Python의 메모리 관리는 자동으로 이루어지므로 직접 관리할 필요는 드뭅니다.


이 섹션에서는 Python의 변수와 자료형에 대한 기본적인 이해를 다졌습니다.