05장: 파이썬 날개 달기

소개

이번 장에서는 파이썬의 기본 사용법을 넘어 생산성을 극대화하고 더욱 효율적인 코드를 작성하기 위한 고급 주제들을 다룹니다. 이 장을 통해 작성한 코드는 보다 견고하고 확장 가능하며 유지 보수가 쉬워질 것입니다.

1. 컨텍스트 매니저 (Context Managers)

컨텍스트 매니저는 파일 열기, 데이터베이스 연결, 락 사용 등에서 자원 할당과 해제를 자동화하는 파이썬 기능입니다. 이는 코드의 가독성을 높이고, 버그 발생 가능성을 줄여줍니다.

1.1 컨텍스트 매니저의 기본 사용법

파이썬에서 가장 흔한 컨텍스트 매니저의 예는 with 구문을 사용하여 파일을 여는 것입니다.

with open('example.txt', 'r') as file:
    data = file.read()
    # file은 블록이 종료되면서 자동으로 닫힙니다.

1.2 사용자 정의 컨텍스트 매니저

컨텍스트 매니저를 직접 구현하려면 __enter__와 __exit__ 메소드를 가진 클래스를 정의하면 됩니다.

class CustomContext:
    def __enter__(self):
        # 자원 할당 혹은 설정
        print("자원 할당")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        # 자원 해제
        print("자원 해제")

with CustomContext() as context:
    print("블록 내부")

이 예제에서는 블록의 시작과 끝을 알아채고 자원을 관리합니다.

2. 제너레이터 (Generators)

제너레이터는 이터레이터를 간단하게 만든 것이며 큰 데이터 세트를 처리할 때 메모리를 절약할 수 있습니다. 제너레이터는 값을 한 번에 하나씩 반환하여 다음 값을 필요로 할 때까지 대기합니다. 이러한 특성을 통해 제너레이터는 큰 데이터 세트를 효율적으로 처리할 수 있습니다.

2.1 제너레이터 함수

제너레이터 함수는 일반 함수처럼 정의되지만 값을 반환할 때 return 대신 yield를 사용합니다.

def simple_generator():
    yield 1
    yield 2
    yield 3

위 함수는 호출될 때마다 차례로 1, 2, 3을 반환하는 제너레이터 객체를 만듭니다.

2.2 무한 제너레이터

제너레이터는 무한 루프를 쉽게 만들 수 있어 주기적으로 반복되는 프로세스를 처리할 때 유용합니다.

def infinite_sequence():
    num = 0
    while True:
        yield num
        num += 1

이 함수는 중지되지 않는 한 무한하게 0부터 시작하여 증가하는 수를 반환합니다.

3. 데코레이터 (Decorators)

데코레이터는 함수나 메소드의 동작을 동적으로 변경하거나 확장할 수 있는 강력한 도구입니다. 이는 코드 재사용성을 크게 높여주며, 주로 로깅, 접근 제어, 계측 등에 사용됩니다.

3.1 데코레이터의 정의 및 사용

데코레이터는 또 다른 함수로 감싸서 특정 로직을 추가하거나 기존 함수의 입력과 출력을 수정할 수 있습니다.

def my_decorator(func):
    def wrapper():
        print("함수 호출 전")
        func()
        print("함수 호출 후")
    return wrapper

@my_decorator
def say_hello():
    print("안녕하세요!")

say_hello()

이 예제에서 say_hello 함수가 호출될 때 데코레이터가 추가한 기능이 함께 실행됩니다.

3.2 여러 데코레이터 결합

여러 데코레이터를 하나의 함수에 적용할 수 있으며, 이는 데코레이터의 순서에 따라 다르게 동작할 수 있습니다.

def decorator_one(func):
    def wrapper():
        print("데코레이터 1 적용")
        func()
    return wrapper

def decorator_two(func):
    def wrapper():
        print("데코레이터 2 적용")
        func()
    return wrapper

@decorator_two
@decorator_one
def display():
    print("전시 함수")

display()

4. 병렬 처리 및 멀티스레딩 (Parallelism and Multithreading)

프로그램 성능을 높이기 위해 병렬 또는 멀티스레딩을 사용할 수 있습니다. 이는 코드가 여러 CPU 코어를 활용하여 작업을 동시에 수행할 수 있게 해줍니다.

4.1 멀티스레딩

멀티스레딩은 I/O bound 작업이 많은 경우 유용합니다. 파이썬의 threading 모듈을 사용하여 스레드를 만들 수 있습니다.

import threading
import time

def thread_function(name):
    print(f"스레드 {name} 시작")
    time.sleep(2)
    print(f"스레드 {name} 종료")

threads = []
for i in range(3):
    thread = threading.Thread(target=thread_function, args=(i,))
    threads.append(thread)
    thread.start()

for thread in threads:
    thread.join()

이 코드는 3개의 스레드를 만들어 각각 2초간 작업을 수행하게 합니다.

4.2 멀티프로세싱

CPU bound 작업의 경우 multiprocessing 모듈이 더 효율적입니다. 이는 프로세스를 만들어 CPU 코어를 최대한 활용할 수 있게 합니다.

from multiprocessing import Process

def process_function(name):
    print(f"프로세스 {name} 시작")
    time.sleep(2)
    print(f"프로세스 {name} 종료")

processes = []
for i in range(3):
    process = Process(target=process_function, args=(i,))
    processes.append(process)
    process.start()

for process in processes:
    process.join()

5. 예외 처리 고급 (Advanced Exception Handling)

예외 처리는 프로그램의 신뢰성을 높이는 데 필수적입니다. 여기서는 고급 예외 처리 기법을 살펴봅니다.

5.1 커스텀 예외 생성

사용자 정의 예외를 만들어 특정 상황에서 발생할 예외를 명시적으로 표현할 수 있습니다.

class CustomError(Exception):
    pass

try:
    raise CustomError("이것은 사용자 정의 예외입니다")
except CustomError as e:
    print(e)

5.2 예외 체이닝

하나의 예외가 다른 예외의 결과일 수 있습니다. 파이썬에서는 raise ... from ... 문법을 사용하여 예외 체인을 만들 수 있습니다.

try:
    raise ValueError("첫 번째 예외")
except ValueError as ve:
    raise KeyError("두 번째 예외") from ve

6. 결론

이번 장에서는 파이썬의 고급 기능을 보다 깊이 있게 탐구하였습니다. 이러한 기술을 활용하면 더욱 견고하고 확장 가능한 코드를 작성할 수 있습니다. 다음 장에서는 데이터 분석에서 파이썬을 이용하는 방법에 대해 알아보겠습니다.

파이썬의 외부 라이브러리

향상된 기능성과 다양한 데이터 처리를 위해 파이썬 개발자들은 외부 라이브러리를 적극적으로 활용합니다. 파이썬 외부 라이브러리란, 광고적인 용어로 개발자들이 개발 주기에 맞춰 공개한 코드 집합을 말합니다. 이들은 파이썬의 기본적인 기능을 신장시키고 복잡한 직무를 효율적으로 수행하도록 돕습니다.

외부 라이브러리란 무엇인가?

외부 라이브러리는 특정 기능을 수행하기 위해 독립적으로 개발된 코드 모음을 말합니다. 이러한 라이브러리를 사용하면, 직접 구현하기 복잡하거나 시간이 많이 드는 작업을 손쉽게 해결할 수 있습니다.

라이브러리는 보통 모듈이라는 단위로 구성되며, 각 모듈은 한 가지 혹은 여러 가지 관련된 기능을 포함합니다. 예를 들어, 수학 관련 연산을 지원하는 math 모듈의 경우 다양한 수리 계산 기능을 제공합니다.

외부 라이브러리 설치 및 관리

파이썬 외부 라이브러리는 PyPI(Python Package Index)라는 중앙 저장소에서 주로 다운로드됩니다. PyPI에는 수십만 개 이상의 패키지가 등록되어 있어, 대부분의 요구에 맞는 라이브러리를 손쉽게 찾아볼 수 있습니다.

pip를 이용한 라이브러리 설치

파이썬의 패키지 관리자 pip를 사용하면 손쉽게 라이브러리를 설치할 수 있습니다. 다음은 기본적인 pip 명령어입니다:

$ pip install 패키지명

예를 들어, 데이터 분석에 널리 사용되는 numpy 라이브러리를 설치하려면:

$ pip install numpy

설치된 라이브러리는 import 구문을 통해 파이썬 스크립트에서 사용할 수 있습니다:

import numpy as np

가상 환경을 활용한 프로젝트 독립성 유지

여러 프로젝트에서 서로 다른 버전의 라이브러리를 사용해야 하는 경우가 많습니다. 이를 위해 파이썬에서는 venv 모듈을 사용하여 가상 환경을 구성할 수 있습니다. 가상 환경은 개별 프로젝트마다 독립적인 의존성을 관리할 수 있어 충돌을 방지합니다.

필수 외부 라이브러리 소개

다양한 분야에서 많이 사용되는 파이썬 라이브러리를 소개하겠습니다. 이들은 데이터 분석, 웹 개발, 머신러닝 등 다양한 응용 프로그램을 개발하는 데 필수적입니다.

1. NumPy

NumPy는 과학 연산을 위한 널리 사용되는 라이브러리로, 고성능 다차원 배열 객체 및 다양한 도구를 제공합니다. 배열 기반 연산을 효율적으로 수행할 수 있어 데이터 분석에 탁월한 성능을 발휘합니다.

2. Pandas

Pandas는 데이터 구조와 데이터 분석 도구를 제공하는 라이브러리입니다. 다차원 데이터를 쉽게 조작하고 분석할 수 있도록 도와주며, 데이터 프레임을 사용하여 다양한 데이터 소스를 손쉽게 다룰 수 있습니다.

3. Matplotlib

Matplotlib는 데이터 시각화를 위한 강력한 라이브러리입니다. 다양한 종류의 차트를 그릴 수 있으며, 사용자 지정이 가능하여 복잡한 데이터 시각화 작업에 적합합니다.

4. Requests

Requests는 HTTP 요청을 쉽게 할 수 있도록 도와주는 라이브러리입니다. 간단한 API 호출 및 웹 크롤링 작업에 유용하며, 효율적이고 인간 친화적인 HTTP 요청을 수행할 수 있습니다.

5. Flask & Django

Flask와 Django는 파이썬 기반의 웹 프레임워크입니다. Flask는 가볍고 모듈화된 구조로, 소규모 프로젝트에 적합합니다. Django는 대규모 웹 애플리케이션 개발에 적합한 강력한 기능을 제공합니다.

6. TensorFlow & PyTorch

이 라이브러리들은 딥러닝과 머신러닝 작업에 주로 사용됩니다. TensorFlow는 Google에서 개발한 라이브러리로, 대규모 데이터 처리와 딥러닝 모델 구현에 효율적입니다. PyTorch는 연구자들 사이에서 인기가 높으며, 동적 연산 그래프와 자연스러운 코드 작성이 장점입니다.

7. Scikit-learn

Scikit-learn은 머신러닝을 위한 라이브러리로, 다양한 머신러닝 알고리즘을 쉽고 빠르게 구현할 수 있도록 도와줍니다. 손쉬운 학습과 평가, 모델 선택 등을 지원합니다.

8. Beautiful Soup

Beautiful Soup은 HTML과 XML 문서를 파싱하고 탐색하기 위한 라이브러리입니다. 손쉽게 웹 데이터를 스크래핑할 수 있도록 돕습니다.

외부 라이브러리 활용 팁

외부 라이브러리를 효율적으로 활용하기 위해 몇 가지 팁을 제공합니다:

  • 문서화 살펴보기: 라이브러리의 공식 문서화는 사용법과 예제, 함수 및 클래스에 대한 설명을 제공합니다. 사용 전에 반드시 확인하세요.
  • 커뮤니티 활용: Stack Overflow, GitHub Issues 등을 통해 질문을 하고 문제를 해결할 수 있습니다.
  • 활용 사례 조사: 비슷한 목적의 프로젝트에서 라이브러리를 어떻게 사용하는지 살펴볼 수 있습니다.

결론

파이썬 외부 라이브러리는 개발자의 생산성을 크게 향상시킵니다. 설치와 사용 방법을 익히고, 각 분야에 맞는 필수 라이브러리를 적절히 활용하여 더 나은 프로그램을 개발하세요. 라이브러리를 효율적으로 통합함으로써 복잡한 문제를 간단하게 해결할 수 있습니다.

파이썬 표준 라이브러리: 범용적이고 강력한 도구의 집합

파이썬은 표준 라이브러리라고 불리는 방대하고 강력한 모듈 집합을 기본적으로 제공합니다. 이 라이브러리는 파이썬의 핵심 기능을 확장하며, 다양한 프로그래밍 작업을 쉽게 수행할 수 있도록 도와줍니다. 표준 라이브러리는 별도의 설치 없이 바로 사용할 수 있기 때문에, 파이썬 프로그래머라면 누구나 익숙하게 사용할 수 있는 강력한 도구입니다.

이 글에서는 파이썬의 표준 라이브러리를 깊이 있게 탐구하고, 자주 사용되는 모듈부터 고급 기능, 그리고 모듈의 효과적인 활용 방법까지 다양한 주제를 다룰 것입니다. 주요 목표는 독자가 파이썬 표준 라이브러리의 잠재적인 강점을 최대한 활용할 수 있도록 돕는 것입니다.

주요 모듈 소개

파이썬 표준 라이브러리는 여러 카테고리로 구성되어 있으며, 각 모듈은 특정 작업을 수행하는 데 특화되어 있습니다. 다음은 그중에서도 자주 사용되는 몇 가지 모듈입니다:

1. os 모듈

파이썬의 os 모듈은 운영 체제와 상호 작용하는 데 필요한 기능을 제공합니다. 크로스 플랫폼 호환성을 보장하면서 파일과 디렉토리 조작, 환경 변수 액세스, 프로세스 관리 등을 수행할 수 있습니다.


import os

# 현재 작업 디렉토리 가져오기
current_directory = os.getcwd()
print("현재 작업 디렉토리:", current_directory)

# 디렉토리 변경
os.chdir('/tmp')
print("디렉토리 변경:", os.getcwd())

# 디렉토리 생성
os.mkdir('new_directory')

# 환경 변수 가져오기
key_value = os.getenv('HOME')
print("HOME 환경 변수:", key_value)

위의 예제에서는 os.getcwd()를 사용해 현재 작업 디렉토리를 가져오고, os.chdir()를 사용해 디렉토리를 변경하는 방법을 보여줍니다. 또한 os.mkdir()로 새로운 디렉토리를 만들고, os.getenv()로 환경 변수를 가져오는 방법을 설명했습니다.

2. sys 모듈

sys 모듈은 파이썬 인터프리터와 상호 작용할 수 있는 다양한 함수를 제공합니다. 스크립트의 실행 환경을 제어하고, 시스템 관련 정보를 다루는 데 유용합니다.


import sys

# 파이썬 버전 확인
print("파이썬 버전:", sys.version)

# 명령 줄 인수 접근
args = sys.argv
print("명령 줄 인수:", args)

# 프로그램 강제 종료
# sys.exit("종료 메시지")

이 예제에서는 sys.version으로 파이썬 버전을 가져오는 방법, sys.argv를 통해 명령 줄 인수에 접근하는 법을 설명했습니다. 또한 sys.exit()를 활용하여 프로그램을 강제 종료하는 방법도 보여줍니다.

3. math 모듈

math 모듈은 수학 계산에 필요한 함수와 상수를 제공합니다. 고급 수학 연산을 쉽게 처리할 수 있도록 다양한 기능을 제공합니다.


import math

# 제곱근 계산
square_root = math.sqrt(16)
print("제곱근:", square_root)

# 삼각 함수
angle = math.radians(90)
print("sin(90도):", math.sin(angle))

# 상수 활용
print("원주율(pi):", math.pi)
print("자연상수(e):", math.e)

위의 예시에서는 math.sqrt()로 제곱근을 계산하고, math.sin()과 math.radians()를 사용하여 삼각함수를 활용하는 방법을 보여줍니다. 마지막으로 math.pi와 math.e와 같은 수학 상수를 사용하는 예를 설명합니다.

4. datetime 모듈

datetime 모듈은 날짜와 시간을 처리하는 데 사용됩니다. 날짜 계산, 형식화, 현재 날짜와 시간 가져오기 등 다양한 작업이 가능합니다.


from datetime import datetime

# 현재 날짜와 시간 가져오기
now = datetime.now()
print("현재 날짜와 시간:", now)

# 특정 날짜 생성
new_years_day = datetime(2023, 1, 1)
print("신년:", new_years_day)

# 날짜 간 차이 계산
delta = now - new_years_day
print("신년 이후 일수:", delta.days)

이 예에서는 datetime.now()를 사용하여 현재 날짜와 시간을 가져오고, 특정 날짜를 생성하는 방법을 설명합니다. 또한 두 날짜 간의 차이를 계산하여 며칠이 지났는지도 보여줍니다.

5. random 모듈

난수 생성이나 임의의 선택을 위한 random 모듈은 다양한 유용한 기능을 제공합니다. 이를 통해 무작위 데이터를 생성하거나 샘플링 작업을 수행할 수 있습니다.


import random

# 0부터 1 사이의 난수 생성
rand_value = random.random()
print("난수:", rand_value)

# 정수 범위 내 난수 생성
rand_int = random.randint(1, 100)
print("1에서 100 사이의 난수:", rand_int)

# 리스트에서 임의의 항목 선택
choices = ['apple', 'banana', 'cherry']
selected = random.choice(choices)
print("임의의 선택:", selected)

앞의 예제에서는 random.random()을 활용해 0과 1 사이의 부동 소수점 난수를 생성하고, random.randint()로 정수 범위 내 난수를 생성했습니다. 또한 random.choice()로 리스트에서 임의의 항목을 선택하는 방법을 탐구했습니다.

고급 모듈

이제 표준 라이브러리에 포함된 고급 모듈을 좀 더 자세히 살펴보겠습니다. 이러한 모듈은 데이터 처리, 네트워킹, 멀티스레딩 등 복잡한 작업을 쉽게 수행할 수 있도록 설계되었습니다.

1. collections 모듈

파이썬의 collections 모듈은 컨테이너 데이터형에 대한 특별한 기능을 제공합니다. 이 모듈은 리스트, 딕셔너리 등과 같은 기본적인 자료형 외에도 다양한 고급 자료형을 제공합니다. 주요 자료형으로는 defaultdictCounterOrderedDictdeque 등이 있습니다.


from collections import Counter, defaultdict

# Counter를 사용한 빈도 계산
elements = ['a', 'b', 'c', 'a', 'b', 'b']
counter = Counter(elements)
print("빈도 수:", counter)

# defaultdict를 사용한 기본값 제공
default_dict = defaultdict(int)
default_dict['missing'] += 1
print("기본값을 가진 딕셔너리:", default_dict)

위의 코드는 Counter 클래스를 활용하여 리스트 내 요소 빈도를 계산하는 방법을 보여주고, defaultdict 클래스를 이용해 존재하지 않는 키에 접근했을 때 기본값을 제공하는 법을 설명합니다.

2. json 모듈

JSON(자바스크립트 객체 표기법)은 데이터를 저장하고 전송하기에 적합한 경량 데이터 교환 형식입니다. 파이썬의 json 모듈은 JSON 데이터를 파싱하고 생성하는 데 광범위하게 사용됩니다.


import json

# 파이썬 객체를 JSON 문자열로 변환
data = {'name': 'John', 'age': 30, 'city': 'New York'}
json_string = json.dumps(data)
print("JSON 문자열:", json_string)

# JSON 문자열을 파이썬 객체로 변환
json_data = '{"name": "Alice", "age": 25, "city": "London"}'
parsed_data = json.loads(json_data)
print("파싱된 데이터:", parsed_data)

위의 예제에서는 json.dumps()를 사용해 파이썬 객체를 JSON 문자열로 변환하는 방법을 보여주며, json.loads()로 JSON 문자열을 파이썬 객체로 파싱하는 과정을 설명합니다.

3. re 모듈

정규표현식은 문자열을 다루는데 매우 강력한 도구입니다. re 모듈은 정규표현식을 사용해 문자열 검색, 매칭, 치환과 같은 다양한 작업을 수행할 수 있게 해줍니다.


import re

# 문자열에서 패턴 일치 여부 확인
pattern = r'\d+'
text = 'There are 25 apples'
match = re.search(pattern, text)
if match:
    print("일치하는 패턴을 찾음:", match.group())
else:
    print("매칭 없음")

# 패턴 치환
result = re.sub(r'apples', 'oranges', text)
print("바뀐 텍스트:", result)

이 코드는 re.search()로 특정 패턴을 문자열에서 찾아내는 방법과 re.sub()로 문자열 패턴을 치환하는 방법을 보여줍니다. 정규표현식은 수많은 입출력 처리에서 강력한 도구로 활용됩니다.

파이썬의 내장 함수

파이썬은 개발자를 위해 풍부한 내장 함수를 제공합니다. 이 함수들은 일반적인 프로그래밍 작업을 간편하게 수행할 수 있도록 도와줍니다. 이번 글에서는 이러한 내장 함수들에 대해 자세히 알아보고, 각 함수의 사용법과 그 용례를 살펴보겠습니다.

1. print() 함수

print() 함수는 가장 많이 사용되는 함수 중 하나로, 콘솔에 출력을 표시하는 데 사용됩니다. 여러 개의 인수를 받아 하나의 문자열로 연결하여 출력할 수 있으며, 기본적으로 문자열 사이에 공백을 추가합니다.

print("Hello, World!")
print("Python", "is", "fun")

결과:

Hello, World!
Python is fun

2. len() 함수

len() 함수는 객체의 길이를 반환합니다. 문자열, 리스트, 튜플, 딕셔너리 등 시퀀스 자료형에 주로 사용됩니다.

string = "Python"
print(len(string))

numbers = [1, 2, 3, 4, 5]
print(len(numbers))

결과:

6
5

3. type() 함수

type() 함수는 객체의 자료형을 반환합니다. 이 함수는 변수가 예상한 타입인지 확인하는 데 유용합니다.

print(type(3))
print(type(3.0))
print(type("Hello"))

결과:

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

4. input() 함수

input() 함수는 사용자로부터 문자열 입력을 받을 때 사용됩니다. 파이썬 3.x에서는 항상 문자열 형태로 입력을 받습니다.

name = input("Enter your name: ")
print("Hello, " + name + "!")

5. sum() 함수

sum() 함수는 숫자 시퀀스의 합계를 계산합니다. 이 함수는 주로 리스트나 튜플의 합계를 구하는 데 사용됩니다.

numbers = [1, 2, 3, 4, 5]
print(sum(numbers))

결과:

15

6. min()와 max() 함수

min() 함수는 시퀀스에서 최소값을, max() 함수는 최대값을 반환합니다. 이 함수들은 숫자 시퀀스의 최솟값과 최댓값을 찾는 데 유용합니다.

numbers = [3, 1, 4, 1, 5, 9]
print(min(numbers))
print(max(numbers))

결과:

1
9

7. sorted() 함수

sorted() 함수는 주어진 시퀀스를 정렬한 결과를 반환합니다. 이 함수는 원래의 리스트를 변경하지 않고 새로운 정렬된 리스트를 생성합니다. 기본적으로 오름차순으로 정렬되며, reverse=True를 사용하면 내림차순으로 정렬됩니다.

numbers = [3, 1, 4, 1, 5, 9]
print(sorted(numbers))
print(sorted(numbers, reverse=True))

결과:

[1, 1, 3, 4, 5, 9]
[9, 5, 4, 3, 1, 1]

8. any()와 all() 함수

any() 함수는 시퀀스 내에서 하나 이상의 요소가 True일 경우 True를 반환하고, 그렇지 않으면 False를 반환합니다. all() 함수는 모든 요소가 True일 경우 True를 반환합니다.

bool_list = [True, False, True]
print(any(bool_list))
print(all(bool_list))

결과:

True
False

9. zip() 함수

zip() 함수는 여러 시퀀스를 병렬로 묶어줍니다. 각 시퀀스의 요소를 튜플로 묶어 나열하며, 시퀀스 중 가장 짧은 것의 길이에 맞춥니다.

list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
zipped = zip(list1, list2)
print(list(zipped))

결과:

[(1, 'a'), (2, 'b'), (3, 'c')]

10. enumerate() 함수

enumerate() 함수는 시퀀스의 요소를 인덱스와 함께 튜플로 반환합니다. 기본적으로 인덱스는 0에서 시작하며, 시작을 다른 숫자로 변경할 수 있습니다.

letters = ['a', 'b', 'c']
for index, letter in enumerate(letters):
    print(index, letter)

결과:

0 a
1 b
2 c

11. range() 함수

range() 함수는 정수 시퀀스를 생성합니다. 이 시퀀스는 주로 반복문에서 사용됩니다. range()는 세 개의 인수를 받을 수 있으며, 각각 시작값, 종료값, 증감값을 의미합니다.

for i in range(5):
    print(i)

for i in range(1, 10, 2):
    print(i)

결과:

0
1
2
3
4
1
3
5
7
9

12. filter() 함수

filter() 함수는 주어진 함수와 시퀀스를 받아서, 함수의 조건을 만족하는 요소를 걸러낸다. 결과값은 필터 객체이며, list()를 통해 리스트로 변환할 수 있다.

def is_even(n):
    return n % 2 == 0

numbers = [1, 2, 3, 4, 5, 6]
even_numbers = filter(is_even, numbers)
print(list(even_numbers))

결과:

[2, 4, 6]

13. map() 함수

map() 함수는 주어진 함수와 시퀀스를 받아서, 함수가 적용된 결과를 돌려준다. 이는 주어진 모든 요소에 함수를 적용할 때 유용하다.

def square(n):
    return n * n

numbers = [1, 2, 3, 4, 5]
squared_numbers = map(square, numbers)
print(list(squared_numbers))

결과:

[1, 4, 9, 16, 25]

14. reduce() 함수

reduce() 함수는 누적 계산을 수행하여 하나의 결과를 반환하는 함수입니다. reduce() 함수는 functools 모듈에서 가져와야 합니다. 주요 사용 케이스는 시퀀스를 누적하여 값을 계산할 때입니다.

from functools import reduce

def add(x, y):
    return x + y

numbers = [1, 2, 3, 4, 5]
total = reduce(add, numbers)
print(total)

결과:

15

위의 예시는 파이썬 내장 함수의 몇 가지 예제이며, 각 함수의 특성과 사용법에 대해 알아보았습니다. 이 외에도 파이썬은 다양한 내장 함수를 제공하며, 각 함수는 특정한 작업을 더 쉽고 빠르게 해결할 수 있도록 도와줍니다.

함수의 사용법을 숙지하고 적절히 활용하면, 더 효율적이고 가독성 있는 코드를 작성할 수 있습니다. 내장 함수들은 이러한 목표를 이루기 위한 기본적인 도구가 될 것입니다.

파이썬의 예외 처리 (Exception Handling in Python)

프로그래밍을 하다 보면 런타임 중 예기치 않은 상황이 발생할 수 있습니다. 이러한 상황을 예외(exception)라고 하며, 파이썬에서는 이러한 예외를 우아하게 처리할 수 있는 다양한 방법을 제공합니다. 이 글에서는 예외의 개념, 파이썬에서 예외를 처리하는 방법, 사용자 정의 예외 생성, 그리고 예외가 발생한 후의 흐름 제어에 대해 상세히 설명합니다.

예외란 무엇인가?

예외란 프로그램의 정상적인 흐름을 방해하는 런타임 오류입니다. 예를 들어, 숫자를 0으로 나누려고 할 때, 존재하지 않는 파일을 열려고 할 때 또는 네트워크가 불안정하여 연결이 끊어질 때 예외가 발생할 수 있습니다. 이러한 오류는 예외로 처리되어야 프로그램이 예기치 않게 종료되는 것을 방지하고, 개발자가 그에 맞는 대응을 할 수 있게 해줍니다.

파이썬의 내장 예외(Exception Classes)

파이썬은 많은 내장(built-in) 예외 클래스들을 제공합니다. 기본적인 예외 클래스는 Exception이며, 모든 내장 예외는 이 클래스에서 파생됩니다. 몇 가지 주요 내장 예외 클래스는 다음과 같습니다:

  • IndexError : 시퀀스 인덱스가 범위를 벗어났을 때 발생합니다.
  • KeyError : 딕셔너너리에서 존재하지 않는 키를 참조할 때 발생합니다.
  • ValueError : 부적절한 값을 연산이나 함수에 제공할 때 발생합니다.
  • TypeError : 부적절한 유형의 인자를 함수에 제공할 때 발생합니다.
  • ZeroDivisionError : 0으로 나누려고 할 때 발생합니다.

파이썬에서 예외 처리하기

파이썬에서는 try-except 블록을 사용하여 예외를 처리합니다. 이 블록은 코드에서 예외가 발생할 수 있는 부분을 감싸고, 예외가 발생했을 때 대처할 로직을 제공합니다.

기본 try-except 구조

try:
    # 잠재적으로 예외가 발생할 수 있는 코드
except SomeException:
    # 예외가 발생했을 때 실행할 코드

이 구조에서는 try 블록 내의 코드가 실행됩니다. 만약 예외가 발생하면, try 블록의 나머지 코드는 무시되고 except 블록으로 넘어갑니다. 예외가 발생하지 않으면 except 블록은 무시됩니다.

여러 개의 except 블록 처리하기

여러 유형의 예외를 각각 다르게 처리하기 위해, 여러 개의 except 블록을 사용할 수 있습니다. 가장 일반적인 사용 예는 다음과 같습니다:

try:
    # 예외가 발생할 수 있는 코드
except FirstException:
    # FirstException을 처리하는 코드
except SecondException:
    # SecondException을 처리하는 코드
except Exception as e:
    # 모든 예외를 포괄하여 처리

이 구조에서는 발생한 예외의 유형에 따라 적합한 except 블록이 선택되어 실행됩니다.

else 블록 사용

try 블록의 코드가 예외 없이 성공적으로 실행되었을 때, else 블록이 실행됩니다. 이는 예외가 발생하지 않을 경우에만 실행되고자 하는 코드를 else 블록에 넣는 데 유용합니다. 예제:

try:
    result = x / y
except ZeroDivisionError:
    print("Cannot divide by zero!")
else:
    print("Division successful, result:", result)

finally 블록 사용

finally 블록은 예외 발생 여부와 상관없이 try 문이 종료될 때 항상 실행됩니다. 보통 정리 작업(Cleanup)을 수행하는 데 사용됩니다.

try:
    file = open('data.txt')
    # 파일에서 작업을 수행
except FileNotFoundError:
    print("File not found!")
finally:
    file.close()

위 코드는 예외 발생 여부와 상관없이 파일을 닫습니다.

사용자 정의 예외

개발자는 필요에 따라 사용자 정의 예외를 만들 수 있습니다. 이는 표준 예외 클래스인 Exception을 상속받아 새로운 예외 클래스를 정의하는 방식으로 수행됩니다.

사용자 정의 예외 클래스 만들기

class CustomException(Exception):
    pass

def some_function(x):
    if x < 0:
        raise CustomException("Negative value not allowed!")

이 예제에서는 CustomException이라는 사용자 정의 예외를 만들고, 특정 조건에서 이 예외가 발생하도록 설정하였습니다.

사용자 정의 예외의 고급 사용

사용자 정의 예외 클래스에 추가적인 정보를 제공하기 위해 생성자를 재정의하곤 합니다.

class DetailedException(Exception):
    def __init__(self, message, value):
        super().__init__(message)
        self.value = value

이 클래스는 예외 메시지와 추가적인 값을 포함하여 예외 처리를 더욱 유연하게 만듭니다.

결론

파이썬의 예외 처리는 프로그램의 안정성을 높이고, 예기치 않은 상황에서도 프로그램이 의도한 대로 동작할 수 있도록 도와줍니다. 예외 처리는 단순히 오류를 감지하는 것에 그치지 않고, 적절히 예외를 다루고 복구하는 방법을 제공하여, 소프트웨어의 유연성과 신뢰성을 개선하는 데 중요한 요소입니다. 본 글을 통해 파이썬에서의 예외 처리 방법 및 사용자 정의 예외 생성에 대한 이해가 깊어지길 바랍니다.