Python์ ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์์ ๋ํ ์ฌ์ธต ๊ฐ์ด๋. async with ๋ฌธ, ๋ฆฌ์์ค ๊ด๋ฆฌ ๊ธฐ๋ฒ, ํจ์จ์ ์ด๊ณ ์์ ์ ์ธ ๋น๋๊ธฐ ์ฝ๋ ์์ฑ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ค๋ฃน๋๋ค.
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์: async with ๋ฌธ๊ณผ ๋ฆฌ์์ค ๊ด๋ฆฌ
๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ํ๋ ์ํํธ์จ์ด ๊ฐ๋ฐ์์ ์ ์ ๋ ์ค์ํด์ง๊ณ ์์ผ๋ฉฐ, ํนํ ์น ์๋ฒ, ๋คํธ์ํฌ ์ ํ๋ฆฌ์ผ์ด์
, ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ๊ณผ ๊ฐ์ด ๋๋์ ๋์ ์์
์ ์ฒ๋ฆฌํ๋ ์ ํ๋ฆฌ์ผ์ด์
์์ ๊ทธ๋ฌํฉ๋๋ค. Python์ asyncio
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋น๋๊ธฐ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ํ๋ ์์ํฌ๋ฅผ ์ ๊ณตํ๋ฉฐ, ๋น๋๊ธฐ ์ปจํ
์คํธ ๊ด๋ฆฌ์๋ ๋น๋๊ธฐ ํ๊ฒฝ์์ ๋ฆฌ์์ค๋ฅผ ๊ด๋ฆฌํ๊ณ ์ ์ ํ ์ ๋ฆฌ๋ฅผ ๋ณด์ฅํ๋ ํต์ฌ ๊ธฐ๋ฅ์
๋๋ค. ์ด ๊ฐ์ด๋์์๋ async with
๋ฌธ๊ณผ ํจ๊ณผ์ ์ธ ๋ฆฌ์์ค ๊ด๋ฆฌ ๊ธฐ๋ฒ์ ์ค์ ์ ๋๊ณ ๋น๋๊ธฐ ์ปจํ
์คํธ ๊ด๋ฆฌ์์ ๋ํ ํฌ๊ด์ ์ธ ๊ฐ์๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ปจํ ์คํธ ๊ด๋ฆฌ์ ์ดํดํ๊ธฐ
๋น๋๊ธฐ ์ธก๋ฉด์ ์์ธํ ์ดํด๋ณด๊ธฐ ์ ์ Python์ ์ปจํ
์คํธ ๊ด๋ฆฌ์์ ๋ํด ๊ฐ๋ตํ๊ฒ ๋ณต์ตํด ๋ณด๊ฒ ์ต๋๋ค. ์ปจํ
์คํธ ๊ด๋ฆฌ์๋ ์ฝ๋ ๋ธ๋ก์ด ์คํ๋๊ธฐ ์ ๊ณผ ํ์ ์ํ๋ ์ค์ ๋ฐ ํด์ ์์
์ ์ ์ํ๋ ๊ฐ์ฒด์
๋๋ค. ์ปจํ
์คํธ ๊ด๋ฆฌ์๋ฅผ ์ฌ์ฉํ๋ ์ฃผ์ ๋ฉ์ปค๋์ฆ์ with
๋ฌธ์
๋๋ค.
ํ์ผ์ ์ด๊ณ ๋ซ๋ ๊ฐ๋จํ ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
with open('example.txt', 'r') as f:
data = f.read()
# ๋ฐ์ดํฐ ์ฒ๋ฆฌ
์ด ์์์ open()
ํจ์๋ ์ปจํ
์คํธ ๊ด๋ฆฌ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค. with
๋ฌธ์ด ์คํ๋๋ฉด ์ปจํ
์คํธ ๊ด๋ฆฌ์์ __enter__()
๋ฉ์๋๊ฐ ํธ์ถ๋์ด ์ผ๋ฐ์ ์ผ๋ก ์ค์ ์์
(์ด ๊ฒฝ์ฐ ํ์ผ์ ์ฝ๋๋ค)์ ์ํํฉ๋๋ค. with
๋ฌธ ๋ด๋ถ์ ์ฝ๋ ๋ธ๋ก ์คํ์ด ์๋ฃ๋ ํ(๋๋ ์์ธ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ) ์ปจํ
์คํธ ๊ด๋ฆฌ์์ __exit__()
๋ฉ์๋๊ฐ ํธ์ถ๋์ด ์ฝ๋๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์๋์ง ๋๋ ์์ธ๊ฐ ๋ฐ์ํ๋์ง์ ๊ด๊ณ์์ด ํ์ผ์ด ์ ๋๋ก ๋ซํ๋๋ก ๋ณด์ฅํฉ๋๋ค.
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์์ ํ์์ฑ
๊ธฐ์กด ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ ๋๊ธฐ์์ด๋ฏ๋ก ์ค์ ๋ฐ ํด์ ์์ ์ด ์ํ๋๋ ๋์ ํ๋ก๊ทธ๋จ ์คํ์ ์ฐจ๋จํฉ๋๋ค. ๋น๋๊ธฐ ํ๊ฒฝ์์ ์ฐจ๋จ ์์ ์ ์ฑ๋ฅ๊ณผ ์๋ต์ฑ์ ์ฌ๊ฐํ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค. ์ฌ๊ธฐ์ ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๊ฐ ๋ฑ์ฅํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ์ฐจ๋จํ์ง ์๊ณ ๋น๋๊ธฐ ์ค์ ๋ฐ ํด์ ์์ ์ ์ํํ์ฌ ๋ณด๋ค ํจ์จ์ ์ด๊ณ ํ์ฅ ๊ฐ๋ฅํ ๋น๋๊ธฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ์์ ์ ์ํํ๊ธฐ ์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ ๊ธ์ ํ๋ํด์ผ ํ๋ ์๋๋ฆฌ์ค๋ฅผ ์๊ฐํด ๋ณด๊ฒ ์ต๋๋ค. ์ ๊ธ ํ๋์ด ์ฐจ๋จ ์์ ์ธ ๊ฒฝ์ฐ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค๋จ์ํฌ ์ ์์ต๋๋ค. ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ฅผ ์ฌ์ฉํ๋ฉด ์ ๊ธ์ ๋น๋๊ธฐ์ ์ผ๋ก ํ๋ํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์๋ตํ์ง ์๊ฒ ๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
๋น๋๊ธฐ ์ปจํ
์คํธ ๊ด๋ฆฌ์์ async with
๋ฌธ
๋น๋๊ธฐ ์ปจํ
์คํธ ๊ด๋ฆฌ์๋ __aenter__()
๋ฐ __aexit__()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํ๋ฉ๋๋ค. ์ด๋ฌํ ๋ฉ์๋๋ ๋น๋๊ธฐ ์ฝ๋ฃจํด์ด๋ฏ๋ก await
ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ awaitํ ์ ์์ต๋๋ค. async with
๋ฌธ์ ๋น๋๊ธฐ ์ปจํ
์คํธ ๊ด๋ฆฌ์์ ์ปจํ
์คํธ ๋ด์์ ์ฝ๋๋ฅผ ์คํํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
๊ธฐ๋ณธ ๊ตฌ๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
async with AsyncContextManager() as resource:
# ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ์์
์ํ
AsyncContextManager()
๊ฐ์ฒด๋ __aenter__()
๋ฐ __aexit__()
๋ฉ์๋๋ฅผ ๊ตฌํํ๋ ํด๋์ค์ ์ธ์คํด์ค์
๋๋ค. async with
๋ฌธ์ด ์คํ๋๋ฉด __aenter__()
๋ฉ์๋๊ฐ ํธ์ถ๋๊ณ ๊ทธ ๊ฒฐ๊ณผ๊ฐ resource
๋ณ์์ ํ ๋น๋ฉ๋๋ค. async with
๋ฌธ ๋ด๋ถ์ ์ฝ๋ ๋ธ๋ก ์คํ์ด ์๋ฃ๋ ํ __aexit__()
๋ฉ์๋๊ฐ ํธ์ถ๋์ด ์ ์ ํ ์ ๋ฆฌ๋ฅผ ๋ณด์ฅํฉ๋๋ค.
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์ ๊ตฌํ
๋น๋๊ธฐ ์ปจํ
์คํธ ๊ด๋ฆฌ์๋ฅผ ๋ง๋ค๋ ค๋ฉด __aenter__()
๋ฐ __aexit__()
๋ฉ์๋๋ฅผ ์ ์ํ๋ ํด๋์ค๋ฅผ ์ ์ํด์ผ ํฉ๋๋ค. __aenter__()
๋ฉ์๋๋ ์ค์ ์์
์ ์ํํด์ผ ํ๊ณ , __aexit__()
๋ฉ์๋๋ ํด์ ์์
์ ์ํํด์ผ ํฉ๋๋ค. ๋ ๋ฉ์๋ ๋ชจ๋ async
ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ์ฝ๋ฃจํด์ผ๋ก ์ ์ํด์ผ ํฉ๋๋ค.
๊ฐ์์ ์๋น์ค์ ๋ํ ๋น๋๊ธฐ ์ฐ๊ฒฐ์ ๊ด๋ฆฌํ๋ ๊ฐ๋จํ ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
import asyncio
class AsyncConnection:
async def __aenter__(self):
self.conn = await self.connect()
return self.conn
async def __aexit__(self, exc_type, exc, tb):
await self.conn.close()
async def connect(self):
# ๋น๋๊ธฐ ์ฐ๊ฒฐ ์๋ฎฌ๋ ์ด์
print("Connecting...")
await asyncio.sleep(1) # ๋คํธ์ํฌ ์ง์ฐ ์๋ฎฌ๋ ์ด์
print("Connected!")
return self
async def close(self):
# ์ฐ๊ฒฐ ๋ซ๊ธฐ ์๋ฎฌ๋ ์ด์
print("Closing connection...")
await asyncio.sleep(0.5) # ๋ซ๊ธฐ ์ง์ฐ ์๋ฎฌ๋ ์ด์
print("Connection closed.")
async def main():
async with AsyncConnection() as conn:
print("Performing operations with the connection...")
await asyncio.sleep(2)
print("Operations complete.")
if __name__ == "__main__":
asyncio.run(main())
์ด ์์์ AsyncConnection
ํด๋์ค๋ __aenter__()
๋ฐ __aexit__()
๋ฉ์๋๋ฅผ ์ ์ํฉ๋๋ค. __aenter__()
๋ฉ์๋๋ ๋น๋๊ธฐ ์ฐ๊ฒฐ์ ์ค์ ํ๊ณ ์ฐ๊ฒฐ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค. __aexit__()
๋ฉ์๋๋ async with
๋ธ๋ก์ ์ข
๋ฃํ ๋ ์ฐ๊ฒฐ์ ๋ซ์ต๋๋ค.
__aexit__()
์์ ์์ธ ์ฒ๋ฆฌ
__aexit__()
๋ฉ์๋๋ exc_type
, exc
, tb
์ ์ธ ๊ฐ์ง ์ธ์๋ฅผ ๋ฐ์ต๋๋ค. ์ด๋ฌํ ์ธ์๋ async with
๋ธ๋ก ๋ด์์ ๋ฐ์ํ ์์ธ์ ๋ํ ์ ๋ณด๋ฅผ ํฌํจํฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ์ง ์์ผ๋ฉด ์ธ ์ธ์ ๋ชจ๋ None
์ด ๋ฉ๋๋ค.
์ด๋ฌํ ์ธ์๋ฅผ ์ฌ์ฉํ์ฌ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ณ ์ ํ์ ์ผ๋ก ์ต์ ํ ์ ์์ต๋๋ค. __aexit__()
๊ฐ True
๋ฅผ ๋ฐํํ๋ฉด ์์ธ๊ฐ ์ต์ ๋์ด ํธ์ถ์์๊ฒ ์ ํ๋์ง ์์ต๋๋ค. __aexit__()
๊ฐ None
(๋๋ False
๋ก ํ๊ฐ๋๋ ๋ค๋ฅธ ๊ฐ)์ ๋ฐํํ๋ฉด ์์ธ๊ฐ ๋ค์ ๋ฐ์ํฉ๋๋ค.
__aexit__()
์์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
class AsyncConnection:
async def __aexit__(self, exc_type, exc, tb):
if exc_type is not None:
print(f"An exception occurred: {exc_type.__name__}: {exc}")
# ์ผ๋ถ ์ ๋ฆฌ ๋๋ ๋ก๊น
์ํ
# True๋ฅผ ๋ฐํํ์ฌ ์ ํ์ ์ผ๋ก ์์ธ ์ต์
return True # ์์ธ ์ต์
else:
await self.conn.close()
์ด ์์์ __aexit__()
๋ฉ์๋๋ ์์ธ๊ฐ ๋ฐ์ํ๋์ง ํ์ธํฉ๋๋ค. ๋ฐ์ํ ๊ฒฝ์ฐ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ธ์ํ๊ณ ์ผ๋ถ ์ ๋ฆฌ๋ฅผ ์ํํฉ๋๋ค. True
๋ฅผ ๋ฐํํ๋ฉด ์์ธ๊ฐ ์ต์ ๋์ด ๋ค์ ๋ฐ์ํ๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ฅผ ์ฌ์ฉํ ๋ฆฌ์์ค ๊ด๋ฆฌ
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ ๋น๋๊ธฐ ํ๊ฒฝ์์ ๋ฆฌ์์ค๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ํนํ ์ ์ฉํฉ๋๋ค. ์ฝ๋ ๋ธ๋ก์ด ์คํ๋๊ธฐ ์ ์ ๋ฆฌ์์ค๋ฅผ ํ๋ํ๊ณ ํ์ ํด์ ํ๋ ๊น๋ํ๊ณ ์์ ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ฌ ์์ธ๊ฐ ๋ฐ์ํ๋๋ผ๋ ๋ฆฌ์์ค๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ ๋ฆฌ๋๋๋ก ํฉ๋๋ค.
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์์ ์ผ๋ฐ์ ์ธ ๋ฆฌ์์ค ๊ด๋ฆฌ ์ฌ์ฉ ์ฌ๋ก๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ: ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ๊ด๋ฆฌ.
- ๋คํธ์ํฌ ์ฐ๊ฒฐ: ์์ผ ๋๋ HTTP ํด๋ผ์ด์ธํธ์ ๊ฐ์ ๋น๋๊ธฐ ๋คํธ์ํฌ ์ฐ๊ฒฐ ์ฒ๋ฆฌ.
- ์ ๊ธ ๋ฐ ์ธ๋งํฌ์ด: ๊ณต์ ๋ฆฌ์์ค์ ๋ํ ์ก์ธ์ค๋ฅผ ๋๊ธฐํํ๊ธฐ ์ํ ๋น๋๊ธฐ ์ ๊ธ ๋ฐ ์ธ๋งํฌ์ด ํ๋ ๋ฐ ํด์ .
- ํ์ผ ์ฒ๋ฆฌ: ๋น๋๊ธฐ ํ์ผ ์์ ๊ด๋ฆฌ.
- ํธ๋์ญ์ ๊ด๋ฆฌ: ๋น๋๊ธฐ ํธ๋์ญ์ ๊ด๋ฆฌ ๊ตฌํ.
์: ๋น๋๊ธฐ ์ ๊ธ ๊ด๋ฆฌ
๋น๋๊ธฐ ํ๊ฒฝ์์ ๊ณต์ ๋ฆฌ์์ค์ ๋ํ ์ก์ธ์ค๋ฅผ ๋๊ธฐํํด์ผ ํ๋ ์๋๋ฆฌ์ค๋ฅผ ์๊ฐํด ๋ณด๊ฒ ์ต๋๋ค. ๋น๋๊ธฐ ์ ๊ธ์ ์ฌ์ฉํ์ฌ ํ ๋ฒ์ ํ๋์ ์ฝ๋ฃจํด๋ง ๋ฆฌ์์ค์ ์ก์ธ์คํ ์ ์๋๋ก ํ ์ ์์ต๋๋ค.
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์์ ํจ๊ป ๋น๋๊ธฐ ์ ๊ธ์ ์ฌ์ฉํ๋ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
import asyncio
async def main():
lock = asyncio.Lock()
async def worker(name):
async with lock:
print(f"{name}: Acquired lock.")
await asyncio.sleep(1)
print(f"{name}: Released lock.")
tasks = [asyncio.create_task(worker(f"Worker {i}")) for i in range(3)]
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(main())
์ด ์์์ asyncio.Lock()
๊ฐ์ฒด๋ ๋น๋๊ธฐ ์ปจํ
์คํธ ๊ด๋ฆฌ์๋ก ์ฌ์ฉ๋ฉ๋๋ค. async with lock:
๋ฌธ์ ์ฝ๋ ๋ธ๋ก์ด ์คํ๋๊ธฐ ์ ์ ์ ๊ธ์ ํ๋ํ๊ณ ํ์ ํด์ ํฉ๋๋ค. ์ด๋ฅผ ํตํด ํ ๋ฒ์ ํ๋์ ์์
์๋ง ๊ณต์ ๋ฆฌ์์ค(์ด ๊ฒฝ์ฐ ์ฝ์ ์ถ๋ ฅ)์ ์ก์ธ์คํ ์ ์์ต๋๋ค.
์: ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ๊ด๋ฆฌ
๋ง์ ์ต์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋น๋๊ธฐ ๋๋ผ์ด๋ฒ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด๋ฌํ ์ฐ๊ฒฐ์ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๋ค์์ ๊ฐ์์ asyncpg
๋ผ์ด๋ธ๋ฌ๋ฆฌ(์ค์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ฌ)๋ฅผ ์ฌ์ฉํ ๊ฐ๋
์ ์์
๋๋ค.
import asyncio
# asyncpg ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฐ์ (๊ฐ์)
import asyncpg
class AsyncDatabaseConnection:
def __init__(self, dsn):
self.dsn = dsn
self.conn = None
async def __aenter__(self):
try:
self.conn = await asyncpg.connect(self.dsn)
return self.conn
except Exception as e:
print(f"Error connecting to database: {e}")
raise
async def __aexit__(self, exc_type, exc, tb):
if self.conn:
await self.conn.close()
print("Database connection closed.")
async def main():
dsn = "postgresql://user:password@host:port/database"
async with AsyncDatabaseConnection(dsn) as db_conn:
try:
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์
์ํ
rows = await db_conn.fetch('SELECT * FROM my_table')
for row in rows:
print(row)
except Exception as e:
print(f"Error during database operation: {e}")
if __name__ == "__main__":
asyncio.run(main())
์ค์ ์ฐธ๊ณ : asyncpg.connect
๋ฐ db_conn.fetch
๋ฅผ ์ฌ์ฉํ๊ณ ์๋ ํน์ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋๋ผ์ด๋ฒ์ ์ค์ ํธ์ถ(์: PostgreSQL์ aiopg
, MongoDB์ motor
๋ฑ)๋ก ๋ฐ๊พธ์ญ์์ค. ๋ฐ์ดํฐ ์์ค ์ด๋ฆ(DSN)์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ๋ผ ๋ค๋ฆ
๋๋ค.
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์ ์ฌ์ฉ ๋ชจ๋ฒ ์ฌ๋ก
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ๋ ค๋ฉด ๋ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๊ณ ๋ คํ์ญ์์ค.
__aenter__()
๋ฐ__aexit__()
๋ฅผ ๋จ์ํ๊ฒ ์ ์ง: ์ด ๋ฉ์๋์์ ๋ณต์กํ๊ฑฐ๋ ์ค๋ ์คํ๋๋ ์์ ์ ์ํํ์ง ๋ง์ญ์์ค. ์ค์ ๋ฐ ํด์ ์์ ์ ์ง์คํ์ญ์์ค.- ์์ธ ์ฒ๋ฆฌ ์ฃผ์:
__aexit__()
๋ฉ์๋๊ฐ ์์ธ๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํ๊ณ ์์ธ๊ฐ ๋ฐ์ํ๋๋ผ๋ ํ์ํ ์ ๋ฆฌ๋ฅผ ์ํํ๋์ง ํ์ธํ์ญ์์ค. - ์ฐจ๋จ ์์
ํผํ๊ธฐ:
__aenter__()
๋๋__aexit__()
์์ ์ฐจ๋จ ์์ ์ ์ํํ์ง ๋ง์ญ์์ค. ๊ฐ๋ฅํ ๊ฒฝ์ฐ ๋น๋๊ธฐ ๋์์ ์ฌ์ฉํ์ญ์์ค. - ๋น๋๊ธฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ: ์ปจํ ์คํธ ๊ด๋ฆฌ์ ๋ด์ ๋ชจ๋ I/O ์์ ์ ๋ํด ๋น๋๊ธฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ณ ์๋์ง ํ์ธํ์ญ์์ค.
- ์ฒ ์ ํ ํ ์คํธ: ์ค๋ฅ ์๋๋ฆฌ์ค๋ฅผ ํฌํจํ ๋ค์ํ ์กฐ๊ฑด์์ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํ๊ธฐ ์ํด ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ฅผ ์ฒ ์ ํ ํ ์คํธํ์ญ์์ค.
- ์๊ฐ ์ด๊ณผ ๊ณ ๋ ค: ๋คํธ์ํฌ ๊ด๋ จ ์ปจํ ์คํธ ๊ด๋ฆฌ์(์: ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋๋ API ์ฐ๊ฒฐ)์ ๊ฒฝ์ฐ ์ฐ๊ฒฐ ์คํจ ์ ๋ฌด๊ธฐํ ์ฐจ๋จ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์๊ฐ ์ด๊ณผ๋ฅผ ๊ตฌํํ์ญ์์ค.
๊ณ ๊ธ ์ฃผ์ ๋ฐ ์ฌ์ฉ ์ฌ๋ก
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์ ์ค์ฒฉ
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ฅผ ์ค์ฒฉํ์ฌ ์ฌ๋ฌ ๋ฆฌ์์ค๋ฅผ ๋์์ ๊ด๋ฆฌํ ์ ์์ต๋๋ค. ๋์ผํ ์ฝ๋ ๋ธ๋ก ๋ด์์ ์ฌ๋ฌ ์ ๊ธ์ ํ๋ํ๊ฑฐ๋ ์ฌ๋ฌ ์๋น์ค์ ์ฐ๊ฒฐํด์ผ ํ๋ ๊ฒฝ์ฐ ์ ์ฉํ ์ ์์ต๋๋ค.
async def main():
lock1 = asyncio.Lock()
lock2 = asyncio.Lock()
async with lock1:
async with lock2:
print("Acquired both locks.")
await asyncio.sleep(1)
print("Releasing locks.")
if __name__ == "__main__":
asyncio.run(main())
์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์ ๋ง๋ค๊ธฐ
์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ฅผ ๋ง๋ค์ด ์ผ๋ฐ์ ์ธ ๋ฆฌ์์ค ๊ด๋ฆฌ ํจํด์ ์บก์ํํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ฝ๋ ์ค๋ณต์ ์ค์ด๊ณ ์ ์ง ๊ด๋ฆฌ์ฑ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ์คํจํ ์์ ์ ์๋์ผ๋ก ๋ค์ ์๋ํ๋ ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
import asyncio
class RetryAsyncContextManager:
def __init__(self, operation, max_retries=3, delay=1):
self.operation = operation
self.max_retries = max_retries
self.delay = delay
async def __aenter__(self):
for i in range(self.max_retries):
try:
return await self.operation()
except Exception as e:
print(f"Attempt {i + 1} failed: {e}")
if i == self.max_retries - 1:
raise
await asyncio.sleep(self.delay)
return None # ์ฌ๊ธฐ์ ๋๋ฌํด์๋ ์ ๋จ
async def __aexit__(self, exc_type, exc, tb):
pass # ์ ๋ฆฌ ํ์ ์์
async def my_operation():
# ์คํจํ ์ ์๋ ์์
์๋ฎฌ๋ ์ด์
if random.random() < 0.5:
raise Exception("Operation failed!")
else:
return "Operation succeeded!"
async def main():
import random
async with RetryAsyncContextManager(my_operation) as result:
print(f"Result: {result}")
if __name__ == "__main__":
asyncio.run(main())
์ด ์๋ ๊ฐ๋ ฅํ ์ปจํ ์คํธ ๊ด๋ฆฌ์์ ์ด์์ธ ์ค๋ฅ ์ฒ๋ฆฌ, ์ฌ์๋ ๋ ผ๋ฆฌ ๋ฐ ์ฌ์ฌ์ฉ์ฑ์ ๋ณด์ฌ์ค๋๋ค.
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์์ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ
๋ ์ผ๋ฐ์ ์ด์ง๋ง ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ฅผ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ์ ๊ฒฐํฉํ์ฌ ๊ฐ๋ ฅํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ๋ง๋ค ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ฌ๋ฐ๋ฅธ ๋ฆฌ์์ค ๊ด๋ฆฌ๋ฅผ ๋ณด์ฅํ๋ฉด์ ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์ค์ ์ฌ๋ก ๋ฐ ์ฌ์ฉ ์ฌ๋ก
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ ๋ค์ํ ์ค์ ์๋๋ฆฌ์ค์ ์ ์ฉํ ์ ์์ต๋๋ค. ๋ช ๊ฐ์ง ์ฃผ์ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์น ํ๋ ์์ํฌ: FastAPI ๋ฐ Sanic๊ณผ ๊ฐ์ ํ๋ ์์ํฌ๋ ๋น๋๊ธฐ ์์ ์ ํฌ๊ฒ ์์กดํฉ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ, API ํธ์ถ ๋ฐ ๊ธฐํ I/O ๋ฐ์ด๋ ์์ ์ ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ฅผ ์ฌ์ฉํ์ฌ ๋์์ฑ๊ณผ ์๋ต์ฑ์ ๊ทน๋ํํฉ๋๋ค.
- ๋ฉ์์ง ํ: ๋ฉ์์ง ํ(์: RabbitMQ, Kafka)์์ ์ํธ ์์ฉ์ ์ข ์ข ๋น๋๊ธฐ ์ฐ๊ฒฐ์ ์ค์ ํ๊ณ ์ ์งํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋๋ผ๋ ์ฐ๊ฒฐ์ด ์ ๋๋ก ๋ซํ๋๋ก ๋ณด์ฅํฉ๋๋ค.
- ํด๋ผ์ฐ๋ ์๋น์ค: ํด๋ผ์ฐ๋ ์๋น์ค(์: AWS S3, Azure Blob Storage)์ ์ก์ธ์คํ๋ ค๋ฉด ์ผ๋ฐ์ ์ผ๋ก ๋น๋๊ธฐ API ํธ์ถ์ด ํ์ํฉ๋๋ค. ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ ์ธ์ฆ ํ ํฐ, ์ฐ๊ฒฐ ํ๋ง ๋ฐ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ฐ๋ ฅํ ๋ฐฉ์์ผ๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
- IoT ์ ํ๋ฆฌ์ผ์ด์ : IoT ์ฅ์น๋ ์ข ์ข ๋น๋๊ธฐ ํ๋กํ ์ฝ์ ์ฌ์ฉํ์ฌ ์ค์ ์๋ฒ์ ํต์ ํฉ๋๋ค. ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ ์ฅ์น ์ฐ๊ฒฐ, ์ผ์ ๋ฐ์ดํฐ ์คํธ๋ฆผ ๋ฐ ๋ช ๋ น ์คํ์ ์์ ์ ์ด๊ณ ํ์ฅ ๊ฐ๋ฅํ ๋ฐฉ์์ผ๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
- ๊ณ ์ฑ๋ฅ ์ปดํจํ : HPC ํ๊ฒฝ์์ ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ ๋ถ์ฐ ๋ฆฌ์์ค, ๋ณ๋ ฌ ๊ณ์ฐ ๋ฐ ๋ฐ์ดํฐ ์ ์ก์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์์ ๋์
๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ ๋ฆฌ์์ค ๊ด๋ฆฌ๋ฅผ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ์ด์ง๋ง ํน์ ์ํฉ์์ ์ฌ์ฉํ ์ ์๋ ๋์์ ์ธ ์ ๊ทผ ๋ฐฉ์์ด ์์ต๋๋ค.
try...finally
๋ธ๋ก:try...finally
๋ธ๋ก์ ์ฌ์ฉํ์ฌ ์์ธ ๋ฐ์ ์ฌ๋ถ์ ๊ด๊ณ์์ด ๋ฆฌ์์ค๊ฐ ํด์ ๋๋๋ก ๋ณด์ฅํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด ์ ๊ทผ ๋ฐฉ์์ ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ๋ ์ฅํฉํ๊ณ ๋ ์ฝ๊ธฐ ์ฌ์ธ ์ ์์ต๋๋ค.- ๋น๋๊ธฐ ๋ฆฌ์์ค ํ: ์์ฃผ ํ๋ ๋ฐ ํด์ ๋๋ ๋ฆฌ์์ค์ ๊ฒฝ์ฐ ๋น๋๊ธฐ ๋ฆฌ์์ค ํ์ ์ฌ์ฉํ์ฌ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ๋ฆฌ์์ค ํ์ ์ ์ํ๊ฒ ํ๋ ๋ฐ ํด์ ํ ์ ์๋ ์ฌ์ ํ ๋น๋ ๋ฆฌ์์ค ํ์ ์ ์งํฉ๋๋ค.
- ์๋ ๋ฆฌ์์ค ๊ด๋ฆฌ: ๊ฒฝ์ฐ์ ๋ฐ๋ผ ์ฌ์ฉ์ ์ง์ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ฆฌ์์ค๋ฅผ ์๋์ผ๋ก ๊ด๋ฆฌํด์ผ ํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด ์ ๊ทผ ๋ฐฉ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ธฐ ์ฝ๊ณ ์ ์ง ๊ด๋ฆฌํ๊ธฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค.
์ด๋ค ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ ์ง๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ํน์ ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ ๋น๋๊ธฐ ํ๊ฒฝ์์ ๋ฆฌ์์ค๋ฅผ ๊ด๋ฆฌํ๋ ๊น๋ํ๊ณ ์์ ์ ์ด๋ฉฐ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ฏ๋ก ๋๋ถ๋ถ์ ๋ฆฌ์์ค ๊ด๋ฆฌ ์๋๋ฆฌ์ค์ ์ผ๋ฐ์ ์ผ๋ก ์ ํธ๋๋ ์ ํ์ ๋๋ค.
๊ฒฐ๋ก
๋น๋๊ธฐ ์ปจํ
์คํธ ๊ด๋ฆฌ์๋ Python์์ ํจ์จ์ ์ด๊ณ ์์ ์ ์ธ ๋น๋๊ธฐ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํ ๊ท์คํ ๋๊ตฌ์
๋๋ค. async with
๋ฌธ์ ์ฌ์ฉํ๊ณ __aenter__()
๋ฐ __aexit__()
๋ฉ์๋๋ฅผ ๊ตฌํํจ์ผ๋ก์จ ๋น๋๊ธฐ ํ๊ฒฝ์์ ๋ฆฌ์์ค๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ ์ฌ๋ฐ๋ฅธ ์ ๋ฆฌ๋ฅผ ๋ณด์ฅํ ์ ์์ต๋๋ค. ์ด ๊ฐ์ด๋์์๋ ๋น๋๊ธฐ ์ปจํ
์คํธ ๊ด๋ฆฌ์์ ๊ตฌ๋ฌธ, ๊ตฌํ, ๋ชจ๋ฒ ์ฌ๋ก ๋ฐ ์ค์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๋ค๋ฃจ๋ ํฌ๊ด์ ์ธ ๊ฐ์๋ฅผ ์ ๊ณตํ์ต๋๋ค. ์ด ๊ฐ์ด๋์ ์ค๋ช
๋ ์ง์นจ์ ๋ฐ๋ฅด๋ฉด ๋ณด๋ค ๊ฐ๋ ฅํ๊ณ ํ์ฅ ๊ฐ๋ฅํ๋ฉฐ ์ ์ง ๊ด๋ฆฌ ๊ฐ๋ฅํ ๋น๋๊ธฐ ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ๊ธฐ ์ํด ๋น๋๊ธฐ ์ปจํ
์คํธ ๊ด๋ฆฌ์๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค. ์ด๋ฌํ ํจํด์ ์์ฉํ๋ฉด ๋ ๊น๋ํ๊ณ Pythonicํ๋ฉฐ ๋ ํจ์จ์ ์ธ ๋น๋๊ธฐ ์ฝ๋๋ฅผ ์ป์ ์ ์์ต๋๋ค. ๋น๋๊ธฐ ์์
์ ํ๋ ์ํํธ์จ์ด์์ ์ ์ ๋ ์ค์ํด์ง๊ณ ์์ผ๋ฉฐ ๋น๋๊ธฐ ์ปจํ
์คํธ ๊ด๋ฆฌ์๋ฅผ ๋ง์คํฐํ๋ ๊ฒ์ ํ๋ ์ํํธ์จ์ด ์์ง๋์ด์๊ฒ ํ์์ ์ธ ๊ธฐ์ ์
๋๋ค.