9.1 컨텍스트 매니저
우리가 자원 접근을 제어하기 위해 with 연산자를 어떻게 사용했는지 기억나? 이걸로 자원이 언제 사용되기 시작하고 언제 종료되는지 정확히 추적할 수 있었어. 비동기 자원에 대해서도 마찬가지야.
비동기 컨텍스트 매니저 (AsyncContextManager)는 비동기 프로그래밍에서 자원을 관리하는 데 사용돼, 비동기 함수 안에서 자원의 정확한 열기와 닫기를 보장해. 일반 컨텍스트 매니저와 비슷하게 작동하지만, 비동기 함수와 async with 구문과 함께 사용하도록 설계되었어.
내가 이걸 자세히 설명하지는 않을거야, 왜냐면 당분간 너희가 직접 비동기 컨텍스트 매니저를 만들 일은 없을 거고, 그때가 되면 다 잊어버릴 테니깐. 근데 개념 자체는 익숙해지고 싶어.
비동기 컨텍스트 매니저 생성하기
비동기 컨텍스트 매니저는 __aenter__와 __aexit__ 메서드를 사용하여 정의해. 이 메서드는 일반 컨텍스트 매니저의 __enter__와 __exit__ 메서드와 유사하지만, 비동기적이야.
-
__aenter__(): 컨텍스트에 들어갈 때 호출되는 비동기 메서드. -
__aexit__(exc_type, exc, tb): 컨텍스트에서 나올 때 호출되는 비동기 메서드. 세 가지 인수: 예외 타입, 예외 자체,(traceback)을 받아.
비동기 컨텍스트 매니저 생성 예제
import asyncio
class AsyncContextManager:
async def __aenter__(self):
print("Enter context")
return self
async def __aexit__(self, exc_type, exc, tb):
print("Exit context")
async def main():
async with AsyncContextManager():
print("Inside context")
asyncio.run(main())
이 코드가 어떻게 실행되는지 보자:
- 비동기적으로 함수
main()이 시작돼 - 함수
main()이 실행되기 시작해 AsyncContextManager타입의 객체가 생성돼AsyncContextManager객체의__aenter__()메서드가 호출돼print("Enter context")가 출력돼- 코드
print("Inside context")가 실행돼 AsyncContextManager객체의__aexit__()메서드가 호출돼- 함수
main()의 실행이 끝나
9.2 사용 예제
위의 예제에서 굳이 비동기 버전의 컨텍스트 매니저를 사용할 필요는 없어 — 코드를 동기적으로 만들어도 작동할 거야.
하지만 비동기 매니저는 블록 안에서 with 비동기 함수가 호출되거나 await 연산자가 사용될 때 필요해.
파일 작업을 위한 비동기 컨텍스트 매니저
이 예제에서는 aiofiles 라이브러리를 사용해 파일을 비동기적으로 읽고 쓰는 방법을 보여줘. 비동기 컨텍스트 매니저 aiofiles.open은 파일을 비동기 컨텍스트에서 안전하게 열고 닫을 수 있게 해줘.
import aiofiles
import asyncio
async def main():
async with aiofiles.open('example.txt', mode='w') as file:
await file.write('Hello, world!')
asyncio.run(main())
네트워크 작업을 위한 비동기 컨텍스트 매니저
이 예제에서는 aiohttp 라이브러리를 사용해 비동기 HTTP 요청을 수행해. 비동기 컨텍스트 매니저 ClientSession과 session.get은 연결을 올바르게 관리해줘.
import aiohttp
import asyncio
async def fetch(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
async def main():
html = await fetch('https://example.com')
print(html)
asyncio.run(main())
비동기 컨텍스트 매니저는 파일, 네트워크 연결 및 열고 닫아야 하는 다른 자원과 같은 자원을 자동으로 관리해줘.
__aenter__와 __aexit__ 메서드는 컨텍스트에 진입하고 나오는 동안 비동기 작업을 수행할 수 있게 해줘, 병렬 작업 수행을 보장해. 비동기 컨텍스트 매니저 사용은 자원 누수를 피하고, 모든 자원이 올바르게 해제되도록 보장해줘.
GO TO FULL VERSION