콜백(Callback) 함수란?

Lucas Kim·2024년 7월 28일
post-thumbnail

콜백 함수에 대한 이해와 활용

Python에서 콜백(callback) 함수는 비동기 작업이 완료된 후 호출되는 함수입니다. 콜백 함수를 사용하는 주된 이유는 비동기 작업이 완료될 때까지 기다리지 않고 다른 작업을 수행할 수 있도록 하기 위함입니다. 이번 글에서는 콜백 함수의 개념과 활용 방법에 대해 설명하겠습니다.

콜백 함수란?

콜백 함수는 다른 함수의 인수로 전달되어, 특정 이벤트나 작업이 완료되었을 때 호출되는 함수입니다. 비동기 작업에서 많이 사용됩니다. 예를 들어, 네트워크 요청이 완료되었을 때 콜백 함수를 호출하여 응답 데이터를 처리할 수 있습니다.

콜백 함수 - 예시

아래 예시는 aiohttp 라이브러리를 사용하여 비동기 HTTP 요청을 수행하고, 요청이 완료된 후 콜백 함수를 호출하는 예제입니다.

import aiohttp
import asyncio

async def get_data(callback):
    async with aiohttp.ClientSession() as session:
        async with session.get('https://jsonplaceholder.typicode.com/posts/1') as response:
            data = await response.json()
            callback(data)

def print_data(data):
    print(data)

async def main():
    await get_data(print_data)

asyncio.run(main())

위 코드에서 get_data 함수는 비동기적으로 데이터를 가져오고, 데이터가 준비되면 callback 함수를 호출합니다. print_data 함수가 콜백 함수로 사용되어 데이터를 출력합니다.

콜백 지옥 (Callback Hell)

콜백 지옥(callback hell)은 콜백 함수를 연속적으로 사용할 때 발생하는 문제입니다. 이는 코드의 가독성과 유지보수성을 떨어뜨립니다. 예를 들어, 아래와 같은 코드가 있습니다.

def step1(callback):
    # 비동기 작업 수행
    callback('step1 result')

def step2(callback):
    # 비동기 작업 수행
    callback('step2 result')

def step3(callback):
    # 비동기 작업 수행
    callback('step3 result')

step1(lambda result1: step2(lambda result2: step3(lambda result3: print(result3))))

위 코드는 비동기 작업을 연속적으로 처리하기 위해 콜백 함수를 중첩해서 사용하고 있습니다. 이는 매우 복잡하고 가독성이 떨어집니다.

해결 방법 - 콜백 함수를 분리

콜백 지옥을 해결하기 위해 콜백 함수를 분리하여 가독성을 높일 수 있습니다.

def step1(callback):
    callback('step1 result')

def step2(callback):
    callback('step2 result')

def step3(callback):
    callback('step3 result')

def step3_callback(result3):
    print(result3)

def step2_callback(result2):
    step3(step3_callback)

def step1_callback(result1):
    step2(step2_callback)

step1(step1_callback)

위 코드는 콜백 함수를 각각의 단계로 분리하여 호출하는 방식으로, 코드의 가독성과 유지보수성을 높였습니다.

FastAPI를 사용한 콜백 함수 예제

FastAPI를 사용하여 비동기 HTTP 요청을 처리하고, 콜백 함수를 사용하는 API 서버를 구현할 수 있습니다.

from fastapi import FastAPI
import aiohttp
import asyncio

app = FastAPI()

async def fetch_data(callback):
    async with aiohttp.ClientSession() as session:
        async with session.get('https://jsonplaceholder.typicode.com/posts/1') as response:
            data = await response.json()
            callback(data)

def process_data(data):
    print(data)

@app.get("/data")
async def get_data():
    await fetch_data(process_data)
    return {"status": "Data processed"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)

위 예제에서 fetch_data 함수는 비동기적으로 데이터를 가져오고, 데이터가 준비되면 process_data 콜백 함수를 호출합니다. /data 엔드포인트에서 이를 호출하여 클라이언트에 응답합니다.

이와 같이, 콜백 함수를 사용하면 비동기 작업이 완료된 후 원하는 동작을 수행할 수 있으며, Python에서도 비동기 처리를 통해 효율적으로 고성능 서버를 구축할 수 있습니다.

profile
AI/ML Research Engineer

0개의 댓글