메뉴 여닫기
개인 메뉴 토글
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

파이썬 개발자가 많이 찾는 검색어

데브카페

1. 기본 문법 및 자료구조

리스트 컴프리헨션 (List Comprehension)

  1. 리스트 컴프리헨션은 리스트를 생성하는 간결하고 효율적인 방법입니다.
  2. 기존 리스트의 요소를 기반으로 새로운 리스트를 만들거나, 특정 조건을 만족하는 요소만 필터링하여 새 리스트를 만들 때 유용합니다.

사용 예시

# 일반적인 for 루프
squares = []
for i in range(10):
    squares.append(i**2)
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 리스트 컴프리헨션
squares_comprehension = [i**2 for i in range(10)]
print(squares_comprehension) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 조건부 리스트 컴프리헨션
even_numbers = [i for i in range(20) if i % 2 == 0]
print(even_numbers) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 중첩 리스트 컴프리헨션
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened_list = [num for row in matrix for num in row]
print(flattened_list) # [1, 2, 3, 4, 5, 6, 7, 8, 9]

딕셔너리 반복 (Dictionary Iteration)

딕셔너리의 키, 값, 또는 키-값 쌍을 반복하는 다양한 방법이 있습니다.

사용 예시

my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}

# 키 반복
print("Keys:")
for key in my_dict:
    print(key)
# name
# age
# city

# 키 반복 (명시적 .keys())
print("\nKeys (explicit):")
for key in my_dict.keys():
    print(key)

# 값 반복
print("\nValues:")
for value in my_dict.values():
    print(value)
# Alice
# 30
# New York

# 키-값 쌍 반복
print("\nItems (key-value pairs):")
for key, value in my_dict.items():
    print(f"{key}: {value}")
# name: Alice
# age: 30
# city: New York

문자열 포매팅 (String Formatting)

문자열에 변수 값을 삽입하거나 특정 형식으로 출력하는 방법입니다. 주로 f-string, `str.format()`, 그리고 `%` 연산자가 사용됩니다.

사용 예시

name = "Bob"
age = 25
pi = 3.14159

# f-string (Python 3.6 이상 권장)
print(f"My name is {name} and I am {age} years old.")
# My name is Bob and I am 25 years old.
print(f"Pi is approximately {pi:.2f}.") # 소수점 둘째 자리까지
# Pi is approximately 3.14.

# str.format()
print("My name is {} and I am {} years old.".format(name, age))
# My name is Bob and I am 25 years old.
print("My name is {0} and I am {1} years old. {0} likes programming.".format(name, age)) # 인덱스 사용
# My name is Bob and I am 25 years old. Bob likes programming.
print("Pi is approximately {:.2f}.".format(pi))
# Pi is approximately 3.14.

# % 연산자 (과거 방식, 새 코드에는 f-string 또는 .format() 권장)
print("My name is %s and I am %d years old." % (name, age))
# My name is Bob and I am 25 years old.
print("Pi is approximately %.2f." % pi)
# Pi is approximately 3.14.

클래스 정의 및 객체 (Class Definition and Objects)

파이썬은 객체 지향 프로그래밍(OOP)을 지원하며, 클래스를 통해 객체를 정의하고 생성할 수 있습니다.

사용 예시

class Dog:
    # 클래스 변수
    species = "Canis familiaris"

    def __init__(self, name, age):
        # 인스턴스 변수
        self.name = name
        self.age = age

    # 인스턴스 메서드
    def bark(self):
        return f"{self.name} says Woof!"

    def description(self):
        return f"{self.name} is {self.age} years old."

# 객체 생성 (인스턴스화)
my_dog = Dog("Buddy", 5)
your_dog = Dog("Lucy", 2)

# 객체의 속성 접근
print(my_dog.name) # Buddy
print(my_dog.age)  # 5
print(my_dog.species) # Canis familiaris

# 객체의 메서드 호출
print(my_dog.bark()) # Buddy says Woof!
print(your_dog.description()) # Lucy is 2 years old.

함수 정의 및 호출 (Function Definition and Calling)

함수는 특정 작업을 수행하는 코드 블록입니다. 코드를 재사용하고 모듈화하는 데 필수적입니다.

사용 예시

# 간단한 함수 정의
def greet(name):
    """주어진 이름으로 인사를 출력하는 함수."""
    print(f"Hello, {name}!")

# 함수 호출
greet("Alice") # Hello, Alice!
greet("Bob")   # Hello, Bob!

# 반환 값이 있는 함수
def add_numbers(a, b):
    """두 숫자를 더한 결과를 반환하는 함수."""
    return a + b

result = add_numbers(10, 20)
print(f"The sum is: {result}") # The sum is: 30

# 기본 매개변수 값
def say_hello(name="Guest"):
    print(f"Hello, {name}!")

say_hello()        # Hello, Guest!
say_hello("Charlie") # Hello, Charlie!

# 가변 인자 (*args, **kwargs)
def print_args(*args, **kwargs):
    print("Positional arguments (args):", args)
    print("Keyword arguments (kwargs):", kwargs)

print_args(1, 2, 3, name="Dave", age=40)
# Positional arguments (args): (1, 2, 3)
# Keyword arguments (kwargs): {'name': 'Dave', 'age': 40}

2. 라이브러리 및 프레임워크 사용법

Pandas Dataframe 생성 및 기본 조작

Pandas는 데이터 분석 및 조작을 위한 강력한 라이브러리입니다. `DataFrame`은 테이블 형태의 데이터를 다루는 데 사용됩니다.

설치 방법

pip install pandas

사용 예시

import pandas as pd
import numpy as np

# 딕셔너리로 DataFrame 생성
data = {
    'Name': ['Alice', 'Bob', 'Charlie', 'David'],
    'Age': [25, 30, 35, 40],
    'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']
}
df = pd.DataFrame(data)
print("DataFrame from dictionary:")
print(df)
#       Name  Age         City
# 0    Alice   25     New York
# 1      Bob   30  Los Angeles
# 2  Charlie   35      Chicago
# 3    David   40      Houston

# 리스트의 리스트로 DataFrame 생성
data_list = [['Emily', 28, 'Boston'], ['Frank', 45, 'Seattle']]
df_list = pd.DataFrame(data_list, columns=['Name', 'Age', 'City'])
print("\nDataFrame from list of lists:")
print(df_list)
#     Name  Age      City
# 0  Emily   28    Boston
# 1  Frank   45   Seattle

# CSV 파일 읽기 (예시: data.csv 파일이 있다고 가정)
# df_csv = pd.read_csv('data.csv')
# print("\nDataFrame from CSV:")
# print(df_csv.head())

# 기본 조작
print("\nDataFrame Info:")
df.info()

print("\nDescribe DataFrame:")
print(df.describe())

print("\nSelect a column:")
print(df['Name'])

print("\nSelect rows by index:")
print(df.loc[0])

print("\nFilter rows:")
print(df[df['Age'] > 30])
#     Name  Age     City
# 2  Charlie   35  Chicago
# 3    David   40  Houston

NumPy 배열 연산 (NumPy Array Operations)

NumPy는 과학 계산을 위한 핵심 라이브러리입니다. 특히 다차원 배열 객체와 배열에 대한 고성능 연산을 제공합니다.

설치 방법

pip install numpy

사용 예시

import numpy as np

# 1차원 배열 생성
arr1d = np.array([1, 2, 3, 4, 5])
print("1D Array:", arr1d)
# 1D Array: [1 2 3 4 5]

# 2차원 배열 (행렬) 생성
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
print("\n2D Array:\n", arr2d)
# 2D Array:
#  [[1 2 3]
#  [4 5 6]]

# 배열 속성
print("\nShape of arr2d:", arr2d.shape) # (2, 3)
print("Dimension of arr2d:", arr2d.ndim) # 2
print("Data type of arr2d:", arr2d.dtype) # int64 (또는 int32)

# 배열 연산 (요소별 연산)
arr_a = np.array([10, 20, 30])
arr_b = np.array([1, 2, 3])
print("\nAddition:", arr_a + arr_b) # [11 22 33]
print("Multiplication:", arr_a * arr_b) # [10 40 90]

# 브로드캐스팅 (Broadcasting)
# 크기가 다른 배열 간의 연산 (조건 만족 시)
arr_c = np.array([[1, 2, 3], [4, 5, 6]])
scalar = 10
print("\nBroadcasting (scalar addition):\n", arr_c + scalar)
# Broadcasting (scalar addition):
#  [[11 12 13]
#  [14 15 16]]

# 슬라이싱 (Slicing)
print("\nSlice arr1d (from index 2 to end):", arr1d[2:]) # [3 4 5]
print("Slice arr2d (first row, all columns):", arr2d[0, :]) # [1 2 3]
print("Slice arr2d (all rows, first column):", arr2d[:, 0]) # [1 4]

# 집계 함수 (Aggregation Functions)
print("\nSum of arr1d:", arr1d.sum()) # 15
print("Mean of arr1d:", arr1d.mean()) # 3.0
print("Max of arr2d:", arr2d.max()) # 6
print("Min of arr2d:", arr2d.min(axis=0)) # [1 2 3] (컬럼별 최소값)

Matplotlib 그래프 그리기

Matplotlib은 파이썬에서 정적, 애니메이션, 상호작용적 시각화를 생성하기 위한 포괄적인 라이브러리입니다.

설치 방법

pip install matplotlib

사용 예시

import matplotlib.pyplot as plt
import numpy as np

# 1. 간단한 선 그래프
x = np.linspace(0, 10, 100) # 0에서 10까지 100개의 점 생성
y = np.sin(x)

plt.figure(figsize=(8, 4)) # 그래프 크기 설정
plt.plot(x, y)
plt.title('Simple Sine Wave')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.grid(True)
plt.show() # 그래프 표시

# 2. 산점도 (Scatter Plot)
np.random.seed(0)
x_scatter = np.random.rand(50) * 10
y_scatter = np.random.rand(50) * 10
colors = np.random.rand(50)
sizes = np.random.rand(50) * 100

plt.figure(figsize=(8, 4))
plt.scatter(x_scatter, y_scatter, c=colors, s=sizes, alpha=0.7)
plt.title('Scatter Plot')
plt.xlabel('X-value')
plt.ylabel('Y-value')
plt.colorbar(label='Color intensity')
plt.show()

# 3. 막대 그래프 (Bar Chart)
categories = ['A', 'B', 'C', 'D']
values = [10, 15, 7, 12]

plt.figure(figsize=(6, 5))
plt.bar(categories, values, color='skyblue')
plt.title('Bar Chart of Categories')
plt.xlabel('Category')
plt.ylabel('Value')
plt.show()

Django REST Framework (DRF) API 튜토리얼

Django REST Framework는 Django 위에 RESTful API를 쉽게 구축할 수 있도록 도와주는 강력한 도구입니다.

설치 방법

1. Django 프로젝트가 이미 설정되어 있다고 가정합니다. 2. DRF 설치:

pip install djangorestframework

3. Django 프로젝트의 `settings.py`에 `'rest_framework'`를 `INSTALLED_APPS`에 추가합니다.

# settings.py
INSTALLED_APPS = [
    # ...
    'rest_framework',
    # ...
]

사용 예시 (간단한 예시)

DRF의 전체 튜토리얼은 방대하므로, 여기서는 기본적인 모델, 시리얼라이저, 뷰셋을 통해 간단한 API를 만드는 과정을 간략히 설명합니다.

  • `models.py` (예: `myapp/models.py`)
from django.db import models

class Snippet(models.Model):
    title = models.CharField(max_length=100, blank=True, default='')
    code = models.TextField()
    linenos = models.BooleanField(default=False)
    language = models.CharField(max_length=100, default='python')
    style = models.CharField(max_length=100, default='friendly')

    class Meta:
        ordering = ['id']
  • `serializers.py` (예: `myapp/serializers.py`)
from rest_framework import serializers
from .models import Snippet

class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        fields = ['id', 'title', 'code', 'linenos', 'language', 'style']
  • `views.py` (예: `myapp/views.py`)
from rest_framework import viewsets
from .models import Snippet
from .serializers import SnippetSerializer

class SnippetViewSet(viewsets.ModelViewSet):
    """
    이 뷰셋은 'list', 'create', 'retrieve', 'update', 'destroy' 작업을 자동으로 제공합니다.
    """
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
  • `urls.py` (프로젝트 `urls.py` 또는 앱 `urls.py`)
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from myapp import views # 'myapp'은 앱 이름에 따라 변경

# 라우터 생성 및 뷰셋 등록
router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet)

urlpatterns = [
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')) # Browsable API를 위한 로그인/로그아웃
]

이후 데이터베이스 마이그레이션 (`python manage.py makemigrations`, `python manage.py migrate`) 및 개발 서버 실행 (`python manage.py runserver`) 후 `http://127.0.0.1:8000/snippets/` 에 접속하면 DRF가 제공하는 API 브라우저를 통해 API를 테스트할 수 있습니다.

Flask 간단한 웹 앱 (Simple Web App)

Flask는 마이크로 웹 프레임워크로, 가볍고 유연하여 소규모 웹 애플리케이션이나 API를 빠르게 개발하는 데 적합합니다.

설치 방법

pip install Flask

사용 예시

`app.py`

from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)

# 기본 라우트
@app.route('/')
def hello_world():
    return 'Hello, World! This is a simple Flask app.'

# 변수를 포함하는 라우트
@app.route('/user/<username>')
def show_user_profile(username):
    return f'User: {username}'

# HTML 템플릿 렌더링 (templates 폴더 필요)
@app.route('/greet')
def greet_page():
    # templates/greet.html 파일이 필요합니다.
    return render_template('greet.html', name='Guest')

# 폼 데이터 처리
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        if username == 'admin' and password == 'password':
            return redirect(url_for('dashboard', user=username))
        else:
            return 'Invalid Credentials!'
    return '''
        <form method="post">
            <p><input type=text name=username></p>
            <p><input type=password name=password></p>
            <p><input type=submit value=Login></p>
        </form>
    '''

@app.route('/dashboard/<user>')
def dashboard(user):
    return f'Welcome to the dashboard, {user}!'

if __name__ == '__main__':
    # 디버그 모드로 실행 (개발 시 유용)
    app.run(debug=True)

`templates/greet.html` (templates 폴더 안에 저장)

<!DOCTYPE html>
<html>
<head>
    <title>Greeting</title>
</head>
<body>
    <h1>Hello, {{ name }} from a template!</h1>
    <p>This is a simple Flask example showing template rendering.</p>
</body>
</html>

실행 방법 터미널에서 `app.py`가 있는 디렉토리로 이동하여 다음 명령 실행:

python app.py

이후 웹 브라우저에서 `http://127.0.0.1:5000/` 에 접속하여 확인합니다.

3. 파일 및 입출력 처리

파일 한 줄씩 읽기 (Read File Line by Line)

파이썬에서 텍스트 파일을 읽는 가장 일반적이고 권장되는 방법은 `with open()` 문을 사용하는 것입니다. 이는 파일을 열고 작업이 끝난 후 자동으로 닫아줍니다.

사용 예시

`example.txt` 파일 생성:

Line 1: Hello, Python!
Line 2: This is a test file.
Line 3: Reading line by line.

파이썬 코드:

# 파일을 한 줄씩 읽기
try:
    with open('example.txt', 'r', encoding='utf-8') as file:
        for line in file:
            print(line.strip()) # .strip()으로 줄 끝의 개행 문자 제거
except FileNotFoundError:
    print("Error: example.txt not found.")
except Exception as e:
    print(f"An error occurred: {e}")

print("\n--- Reading all lines into a list ---")
# 모든 줄을 리스트로 읽기
try:
    with open('example.txt', 'r', encoding='utf-8') as file:
        lines = file.readlines()
        for i, line in enumerate(lines):
            print(f"Line {i+1}: {line.strip()}")
except FileNotFoundError:
    print("Error: example.txt not found.")

CSV 파일에 데이터 쓰기 (Write to CSV)

CSV (Comma Separated Values) 파일은 데이터를 쉼표로 구분하여 저장하는 일반적인 형식입니다. 파이썬의 `csv` 모듈을 사용하여 쉽게 읽고 쓸 수 있습니다.

사용 예시

import csv

# 쓰기 데이터
data_to_write = [
    ['Name', 'Age', 'City'],
    ['Alice', 30, 'New York'],
    ['Bob', 24, 'London'],
    ['Charlie', 35, 'Paris']
]

# CSV 파일에 쓰기
try:
    with open('output.csv', 'w', newline='', encoding='utf-8') as csvfile:
        csv_writer = csv.writer(csvfile)
        csv_writer.writerows(data_to_write) # 여러 행 한 번에 쓰기
    print("Data successfully written to output.csv")
except IOError as e:
    print(f"Error writing to file: {e}")

# CSV 파일 읽기 (확인용)
print("\n--- Reading back from output.csv ---")
try:
    with open('output.csv', 'r', encoding='utf-8') as csvfile:
        csv_reader = csv.reader(csvfile)
        for row in csv_reader:
            print(row)
except FileNotFoundError:
    print("Error: output.csv not found.")
except Exception as e:
    print(f"An error occurred: {e}")

실행 후 `output.csv` 파일이 생성되며 다음과 같은 내용이 저장됩니다:

Name,Age,City
Alice,30,New York
Bob,24,London
Charlie,35,Paris

JSON 데이터 파싱 (JSON Data Parsing)

JSON (JavaScript Object Notation)은 경량의 데이터 교환 형식입니다. 파이썬의 `json` 모듈을 사용하여 JSON 데이터를 파싱(읽기)하고 생성(쓰기)할 수 있습니다.

사용 예시

import json

# JSON 문자열
json_string = '''
{
    "name": "Jane Doe",
    "age": 28,
    "isStudent": false,
    "courses": ["History", "Math", "Science"],
    "address": {
        "street": "123 Main St",
        "city": "Anytown",
        "zipCode": "12345"
    }
}
'''

# JSON 문자열 파싱 (JSON -> Python Dict/List)
data = json.loads(json_string)

print("Parsed data (Python Dictionary):", data)
print("Name:", data['name'])
print("First course:", data['courses'][0])
print("City:", data['address']['city'])

# Python Dict/List를 JSON 문자열로 변환 (Python Dict/List -> JSON)
new_data = {
    'product': 'Laptop',
    'price': 1200,
    'features': ['fast CPU', 'large RAM'],
    'available': True
}

json_output = json.dumps(new_data, indent=4) # indent=4로 보기 좋게 포맷팅
print("\nPython Dictionary converted to JSON string:")
print(json_output)

# JSON 파일 읽기/쓰기 (예시)
# file_data.json 파일을 생성합니다.
# with open('file_data.json', 'w', encoding='utf-8') as f:
#     json.dump(new_data, f, indent=4, ensure_ascii=False)
# print("\nData written to file_data.json")

# with open('file_data.json', 'r', encoding='utf-8') as f:
#     loaded_data = json.load(f)
# print("\nData loaded from file_data.json:", loaded_data)

4. 에러 및 디버깅

예외 처리와 트레이스백 분석

예외(Exception)는 프로그램 실행 중 발생하는 오류입니다. 파이썬은 `try-except-finally` 블록을 사용하여 예외를 처리하고, 오류 발생 시 `traceback`을 통해 문제의 원인을 파악할 수 있도록 돕습니다.

사용 예시

# 1. 간단한 예외 처리 (ZeroDivisionError)
def divide_numbers(a, b):
    try:
        result = a / b
        print(f"Result: {result}")
    except ZeroDivisionError:
        print("Error: Cannot divide by zero!")
    except TypeError:
        print("Error: Invalid type for division.")
    except Exception as e: # 모든 예외를 잡는 일반적인 예외 처리
        print(f"An unexpected error occurred: {e}")
    finally:
        print("Division attempt complete.") # 예외 발생 여부와 상관없이 항상 실행

divide_numbers(10, 2)
# Result: 5.0
# Division attempt complete.

divide_numbers(10, 0)
# Error: Cannot divide by zero!
# Division attempt complete.

divide_numbers(10, 'a')
# Error: Invalid type for division.
# Division attempt complete.

# 2. 트레이스백 (Traceback) 이해
# 예외가 처리되지 않았을 때 파이썬 인터프리터가 출력하는 오류 정보.
# 오류가 어디서, 어떤 순서로 발생했는지 보여줍니다.
def func_c():
    return 10 / 0 # ZeroDivisionError 발생

def func_b():
    return func_c()

def func_a():
    return func_b()

# 아래 코드를 주석 처리하여 실행하면 트레이스백을 볼 수 있습니다.
# try:
#     func_a()
# except Exception as e:
#     print(f"\nCaught an exception: {e}")
#     import traceback
#     traceback.print_exc() # 현재 예외의 트레이스백 출력

위 예시에서 `func_a()`를 호출하면 `func_a -> func_b -> func_c` 순서로 호출되다가 `func_c`에서 `ZeroDivisionError`가 발생합니다. 트레이스백은 이 호출 스택을 역순으로 보여주어 오류의 근원지를 파악하는 데 도움을 줍니다.

특정 에러 메시지 해결 방법

개발자들이 구글에서 가장 많이 검색하는 것 중 하나는 특정 에러 메시지의 해결 방법입니다. 에러 메시지는 오류의 종류와 발생 원인에 대한 중요한 힌트를 제공합니다.

예시: `TypeError: 'int' object is not subscriptable`

이 에러는 정수(int) 객체에 대해 인덱싱(subscripting, `[]` 사용)을 시도했을 때 발생합니다. 즉, 리스트나 딕셔너리처럼 인덱스를 통해 접근할 수 없는 타입에 접근하려고 할 때 나타납니다.

발생 원인

  • 변수가 예상과 달리 정수형인데, 리스트처럼 `variable[index]` 형태로 접근하려 할 때.
  • 함수나 메서드가 정수를 반환하는데, 그 반환 값에 다시 인덱싱을 시도할 때.

사용 예시 및 해결 방법

# 잘못된 사용 예시
my_number = 10
# print(my_number[0]) # TypeError: 'int' object is not subscriptable

# 올바른 사용 예시 (정수 자체를 사용)
print(my_number) # 10

# 흔한 실수: 리스트가 아닌 단일 정수를 순회하려고 할 때
# def process_data(data):
#     for item in data:
#         print(item)

# process_data(123) # TypeError: 'int' object is not iterable (이 경우 'subscriptable' 아님)

# 올바른 해결: 데이터 타입 확인
def process_data_correct(data):
    if isinstance(data, (list, tuple, str)): # iterable 타입인지 확인
        for item in data:
            print(item)
    else:
        print(f"Data is not iterable, received: {type(data)}")

process_data_correct(123) # Data is not iterable, received: <class 'int'>
process_data_correct([1, 2, 3]) # 1, 2, 3

# 또 다른 예시: 함수 반환 값이 예상과 다를 때
def get_first_element(some_list):
    if some_list:
        return some_list[0]
    else:
        return 0 # 실수: 빈 리스트일 때 정수를 반환

my_list = []
# result = get_first_element(my_list)
# print(result[0]) # TypeError: 'int' object is not subscriptable (result가 0이기 때문)

# 올바른 해결: 반환 타입 일관성 유지 또는 반환 값 처리
def get_first_element_corrected(some_list):
    if some_list:
        return some_list[0]
    else:
        return None # None을 반환하여 명확하게 "없음"을 나타냄

corrected_result = get_first_element_corrected(my_list)
if corrected_result is not None:
    print(corrected_result[0]) # 이제 이 줄은 실행되지 않음
else:
    print("List was empty.")

해결 전략:

  • 변수 타입 확인: `print(type(variable))`을 사용하여 변수의 실제 타입을 확인합니다.
  • 코드 로직 검토: 인덱싱을 시도하는 부분에서 해당 변수가 왜 정수가 되었는지 역추적합니다.
  • 디버깅 도구 사용: PDB (아래 참조) 또는 IDE의 디버거를 사용하여 코드 실행 흐름을 따라가며 변수 값을 확인합니다.

PDB (Python Debugger) 사용법

PDB는 파이썬에 내장된 대화형 소스 코드 디버거입니다. 코드를 한 줄씩 실행하며 변수 값을 확인하고 실행 흐름을 제어할 수 있습니다.

사용 방법

1. 스크립트 내에서 호출:

   디버깅을 시작할 지점에 `import pdb; pdb.set_trace()`를 삽입합니다.
import pdb

def calculate_sum(a, b):
    result = a + b
    pdb.set_trace() # 이 지점에서 디버거가 실행됩니다.
    final_result = result * 2
    return final_result

print(calculate_sum(5, 3))

2. 명령줄에서 실행:

    python -m pdb your_script.py

주요 PDB 명령어

  • `n` (next): 다음 줄로 이동 (함수 호출 내부로 들어가지 않음)
  • `s` (step): 다음 줄로 이동 (함수 호출 내부로 들어감)
  • `c` (continue): 다음 브레이크포인트까지 또는 프로그램 끝까지 실행
  • `p <variable>` (print): 변수 값 출력 (예: `p result`)
  • `l` (list): 현재 위치 주변의 코드 표시
  • `b <line_number>` (breakpoint): 특정 줄에 브레이크포인트 설정 (예: `b 7`)
  • `cl` (clear): 모든 브레이크포인트 제거 (또는 `cl <breakpoint_number>`)
  • `q` (quit): 디버거 종료
  • `h` (help): 도움말 표시 (또는 `h <command>`로 특정 명령어 도움말)

PDB 세션 예시

`pdb.set_trace()`를 포함한 `calculate_sum.py` 파일을 생성하고 실행:

$ python calculate_sum.py
> /path/to/calculate_sum.py(5)calculate_sum()
-> final_result = result * 2
(Pdb) n
> /path/to/calculate_sum.py(6)calculate_sum()
-> return final_result
(Pdb) p result
8
(Pdb) s
--Return--
> /path/to/calculate_sum.py(6)calculate_sum()->16
-> return final_result
(Pdb) p final_result
16
(Pdb) c
16

5. 특정 기능 구현

HTTP 요청 보내기 (HTTP Requests)

웹에서 데이터를 가져오거나 API와 통신하기 위해 HTTP 요청을 보냅니다. 파이썬에서는 `requests` 라이브러리가 가장 많이 사용되고 권장됩니다.

설치 방법

pip install requests

사용 예시

import requests

# 1. GET 요청 (데이터 가져오기)
try:
    response = requests.get('https://jsonplaceholder.typicode.com/todos/1')
    response.raise_for_status() # HTTP 오류가 발생하면 예외 발생
    data = response.json() # JSON 응답을 파이썬 딕셔너리로 변환
    print("GET Request Data:")
    print(data)
    print(f"User ID: {data['userId']}, Title: {data['title']}")
except requests.exceptions.HTTPError as errh:
    print(f"Http Error: {errh}")
except requests.exceptions.ConnectionError as errc:
    print(f"Error Connecting: {errc}")
except requests.exceptions.Timeout as errt:
    print(f"Timeout Error: {errt}")
except requests.exceptions.RequestException as err:
    print(f"Something Else: {err}")

# 2. POST 요청 (데이터 보내기)
post_data = {
    'title': 'foo',
    'body': 'bar',
    'userId': 1
}
try:
    post_response = requests.post('https://jsonplaceholder.typicode.com/posts', json=post_data)
    post_response.raise_for_status()
    created_post = post_response.json()
    print("\nPOST Request Response:")
    print(created_post)
    print(f"New post ID: {created_post['id']}")
except requests.exceptions.RequestException as e:
    print(f"Error during POST request: {e}")

# 3. 사용자 정의 헤더를 포함한 요청
headers = {'User-Agent': 'MyPythonApp/1.0', 'Accept': 'application/json'}
try:
    headers_response = requests.get('https://httpbin.org/headers', headers=headers)
    headers_response.raise_for_status()
    print("\nRequest with Custom Headers:")
    print(headers_response.json())
except requests.exceptions.RequestException as e:
    print(f"Error with headers request: {e}")

정규 표현식 (Regular Expressions - RegEx)

정규 표현식은 문자열에서 특정 패턴을 검색, 일치시키고, 조작하는 강력한 도구입니다. 파이썬의 `re` 모듈을 사용합니다.

사용 예시

import re

text = "The quick brown fox jumps over the lazy dog. My email is test@example.com."

# 1. 패턴 검색 (re.search)
# re.search()는 패턴이 문자열에서 처음 나타나는 위치를 찾아 Match 객체를 반환합니다.
match = re.search(r'fox', text)
if match:
    print(f"\n'fox' found at index {match.start()} to {match.end()} (span: {match.span()})")
    print(f"Matched text: {match.group()}")
# 'fox' found at index 16 to 19 (span: (16, 19))
# Matched text: fox

# 2. 모든 일치 항목 찾기 (re.findall)
# re.findall()은 패턴과 일치하는 모든 비겹치는 문자열 목록을 반환합니다.
numbers = "The price is $12.99, tax is $2.50, total is $15.49."
prices = re.findall(r'\$\d+\.\d{2}', numbers)
print(f"\nFound prices: {prices}")
# Found prices: ['$12.99', '$2.50', '$15.49']

# 3. 문자열 대체 (re.sub)
# re.sub()는 문자열에서 패턴과 일치하는 부분을 다른 문자열로 대체합니다.
censored_text = re.sub(r'quick|lazy', '***', text)
print(f"\nCensored text: {censored_text}")
# Censored text: The *** brown fox jumps over the *** dog. My email is test@example.com.

# 4. 이메일 주소 추출 (복잡한 패턴 예시)
email_regex = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
email_match = re.search(email_regex, text)
if email_match:
    print(f"\nFound email: {email_match.group()}")
# Found email: test@example.com.

# 5. 패턴 컴파일 (자주 사용되는 패턴의 성능 향상)
# re.compile()을 사용하여 패턴을 미리 컴파일하면 반복적인 검색 시 성능 이점.
compiled_pattern = re.compile(r'\b\w{4}\b') # 4글자 단어
words = "This is a test with many different words."
found_words = compiled_pattern.findall(words)
print(f"\n4-letter words: {found_words}")
# 4-letter words: ['This', 'test', 'with']

날짜 및 시간 포매팅 (Datetime Formatting)

파이썬의 `datetime` 모듈은 날짜와 시간을 다루는 표준 라이브러리입니다. `strftime()` 및 `strptime()` 메서드를 사용하여 날짜/시간 객체를 문자열로 변환하거나 그 반대로 변환할 수 있습니다.

사용 예시

from datetime import datetime, timedelta

# 현재 날짜 및 시간 가져오기
now = datetime.now()
print(f"Current datetime: {now}") # 예: 2023-10-27 10:30:45.123456

# 1. datetime 객체를 문자열로 포매팅 (strftime)
# %Y: 4자리 연도, %m: 2자리 월, %d: 2자리 일
# %H: 24시간 형식 시, %M: 2자리 분, %S: 2자리 초
# %A: 요일 전체 이름, %B: 월 전체 이름
formatted_date = now.strftime("%Y-%m-%d %H:%M:%S")
print(f"Formatted date (YYYY-MM-DD HH:MM:SS): {formatted_date}")
# 예: 2023-10-27 10:30:45

formatted_custom = now.strftime("오늘은 %A, %Y년 %m월 %d일 입니다.")
print(f"Custom format: {formatted_custom}")
# 예: 오늘은 금요일, 2023년 10월 27일 입니다.

# 2. 문자열을 datetime 객체로 파싱 (strptime)
date_string = "2023-01-15 14:30:00"
parsed_date = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")
print(f"\nParsed datetime from string: {parsed_date}")
# Parsed datetime from string: 2023-01-15 14:30:00

# 다른 형식의 문자열 파싱
another_date_string = "January 1, 2024"
parsed_another = datetime.strptime(another_date_string, "%B %d, %Y")
print(f"Parsed another format: {parsed_another}")
# Parsed another format: 2024-01-01 00:00:00

# 3. 날짜 및 시간 계산 (timedelta)
one_day = timedelta(days=1)
one_hour_ago = now - timedelta(hours=1)
next_week = now + timedelta(weeks=1)

print(f"\nOne hour ago: {one_hour_ago.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Next week: {next_week.strftime('%Y-%m-%d %H:%M:%S')}")

# 두 날짜 간의 차이
date1 = datetime(2023, 1, 1)
date2 = datetime(2023, 1, 31)
difference = date2 - date1
print(f"\nDifference between dates: {difference.days} days") # 30 days

멀티스레딩 또는 멀티프로세싱 (Multithreading/Multiprocessing)

파이썬에서 동시성을 구현하는 두 가지 주요 방법입니다.

  • 멀티스레딩 (threading 모듈): 같은 프로세스 내에서 여러 스레드를 실행합니다. GIL(Global Interpreter Lock) 때문에 CPU 바운드 작업에서는 성능 향상이 제한적이지만, I/O 바운드 작업 (네트워크 요청, 파일 읽기/쓰기)에는 유용합니다.
  • 멀티프로세싱 (multiprocessing 모듈): 별도의 프로세스를 생성하여 각각의 파이썬 인터프리터를 실행합니다. GIL의 영향을 받지 않아 CPU 바운드 작업에 적합합니다.

사용 예시 (간단한 비교)

import time
import threading
import multiprocessing

# CPU 바운드 작업 (시간 소모적인 계산)
def cpu_bound_task(n):
    sum_val = 0
    for i in range(n):
        sum_val += i * i
    return sum_val

# I/O 바운드 작업 (네트워크 요청 또는 파일 I/O 시뮬레이션)
def io_bound_task(duration):
    time.sleep(duration) # I/O 작업 대기 시간 시뮬레이션
    return "IO task finished"

# --- 단일 스레드/프로세스 실행 ---
print("--- Single process/thread ---")
start_time = time.perf_counter()
cpu_bound_task(10_000_000)
io_bound_task(1)
end_time = time.perf_counter()
print(f"Single execution time: {end_time - start_time:.4f} seconds\n")

# --- 멀티스레딩 예시 (I/O 바운드에 적합) ---
print("--- Multithreading Example ---")
start_time = time.perf_counter()
threads = []
for _ in range(3): # 3개의 I/O 작업
    thread = threading.Thread(target=io_bound_task, args=(1,))
    threads.append(thread)
    thread.start()

for thread in threads:
    thread.join() # 스레드가 끝날 때까지 기다림

end_time = time.perf_counter()
print(f"Multithreading execution time (I/O bound): {end_time - start_time:.4f} seconds\n")
# 예상: 약 1초 (병렬로 실행되므로 가장 긴 작업 시간에 수렴)

# --- 멀티프로세싱 예시 (CPU 바운드에 적합) ---
print("--- Multiprocessing Example ---")
start_time = time.perf_counter()
processes = []
for _ in range(3): # 3개의 CPU 작업
    process = multiprocessing.Process(target=cpu_bound_task, args=(10_000_000,))
    processes.append(process)
    process.start()

for process in processes:
    process.join() # 프로세스가 끝날 때까지 기다림

end_time = time.perf_counter()
print(f"Multiprocessing execution time (CPU bound): {end_time - start_time:.4f} seconds\n")
# 예상: 단일 실행 시간의 약 1/N (N은 코어 수)

참고: 실제 성능은 시스템의 코어 수, GIL의 영향, 작업의 성격에 따라 크게 달라질 수 있습니다.

데이터베이스 연결 및 쿼리 실행

파이썬에서 데이터베이스와 상호작용하기 위한 방법은 사용하는 데이터베이스 시스템에 따라 다릅니다. 여기서는 SQLite (파이썬 내장), PostgreSQL, MySQL의 기본적인 연결 및 쿼리 실행 예시를 보여줍니다.

SQLite (내장)

별도의 설치 없이 파이썬에 내장되어 있습니다. 간단한 로컬 데이터베이스에 적합합니다.

사용 예시

import sqlite3

# 데이터베이스 연결 (파일이 없으면 새로 생성)
conn = sqlite3.connect('example.db')
cursor = conn.cursor()

# 테이블 생성
cursor.execute('''
    CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY,
        name TEXT NOT NULL,
        age INTEGER
    )
''')
conn.commit() # 변경사항 커밋

# 데이터 삽입
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Alice', 30))
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Bob', 25))
conn.commit()

# 데이터 조회
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall() # 모든 결과 가져오기
print("\nUsers in SQLite:")
for row in rows:
    print(row)
# (1, 'Alice', 30)
# (2, 'Bob', 25)

# 특정 조건으로 조회
cursor.execute("SELECT name FROM users WHERE age > ?", (28,))
names = cursor.fetchall()
print("\nUsers older than 28:")
for name in names:
    print(name[0])
# Alice

# 연결 종료
conn.close()

PostgreSQL/MySQL (외부 라이브러리 필요)

PostgreSQL의 경우 `psycopg2`, MySQL의 경우 `mysql-connector-python` 또는 `PyMySQL` 라이브러리가 많이 사용됩니다.

설치 방법 (예: PostgreSQL)
pip install psycopg2-binary # 바이너리 버전 설치 권장
사용 예시 (PostgreSQL)
import psycopg2

# 데이터베이스 연결 정보
DB_HOST = "localhost"
DB_NAME = "mydatabase"
DB_USER = "myuser"
DB_PASSWORD = "mypassword"

try:
    conn = psycopg2.connect(
        host=DB_HOST,
        database=DB_NAME,
        user=DB_USER,
        password=DB_PASSWORD
    )
    cursor = conn.cursor()

    # 테이블 생성 (스키마가 다를 수 있음)
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS products (
            id SERIAL PRIMARY KEY,
            name VARCHAR(100) NOT NULL,
            price NUMERIC(10, 2)
        )
    ''')
    conn.commit()

    # 데이터 삽입
    cursor.execute("INSERT INTO products (name, price) VALUES (%s, %s)", ('Laptop', 1200.50))
    cursor.execute("INSERT INTO products (name, price) VALUES (%s, %s)", ('Mouse', 25.00))
    conn.commit()

    # 데이터 조회
    cursor.execute("SELECT * FROM products")
    products = cursor.fetchall()
    print("\nProducts in PostgreSQL:")
    for product in products:
        print(product)

except psycopg2.Error as e:
    print(f"Error connecting to PostgreSQL or executing query: {e}")
finally:
    if conn:
        cursor.close()
        conn.close()
        print("PostgreSQL connection closed.")

참고: MySQL의 경우에도 `mysql.connector` 또는 `pymysql`을 임포트하고 연결 문자열 및 쿼리 구문만 변경하면 유사하게 사용할 수 있습니다.

Comments

목차