Skip to main content

๐Ÿ“š python ๊ธฐ๋ณธ ๊ฐœ๋…

1. ํŒŒ์ด์ฌ ์ž๋ฃŒ๊ตฌ์กฐ (Data Structures)โ€‹

์ž๋ฃŒ๊ตฌ์กฐ๋Š” ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ํŒŒ์ด์ฌ์€ ๋‹ค์–‘ํ•œ ๋‚ด์žฅ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฆฌ์ŠคํŠธ (List - list)
    • ํŠน์ง•: ์ˆœ์„œ๊ฐ€ ์žˆ๊ณ , ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ(mutable) ์‹œํ€€์Šค. ์ค‘๋ณต๋œ ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ์š”์†Œ์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค.
    • ๋™์ž‘: ์š”์†Œ ์ถ”๊ฐ€(append, insert), ์‚ญ์ œ(remove, pop), ๋ณ€๊ฒฝ์ด ์ž์œ ๋กญ์Šต๋‹ˆ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ ๋™์  ๋ฐฐ์—ด๋กœ ๊ตฌํ˜„๋˜์–ด ํฌ๊ธฐ๊ฐ€ ๋ณ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์šฉ๋„: ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์— ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ํŠœํ”Œ (Tuple - tuple)
    • ํŠน์ง•: ์ˆœ์„œ๊ฐ€ ์žˆ์ง€๋งŒ, ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ(immutable) ์‹œํ€€์Šค. ์ค‘๋ณต๋œ ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ์š”์†Œ์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค.
    • ๋™์ž‘: ์ƒ์„ฑ ํ›„์—๋Š” ์š”์†Œ๋ฅผ ์ถ”๊ฐ€, ์‚ญ์ œ, ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ๋ณด๋‹ค ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ ๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ  ๋ฐ˜๋ณต ์†๋„๊ฐ€ ์•ฝ๊ฐ„ ๋” ๋น ๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์šฉ๋„: ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•„์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ ๋ฌถ์Œ (์˜ˆ: ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’, ๋”•์…”๋„ˆ๋ฆฌ ํ‚ค์˜ ์ผ๋ถ€)์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ๋”•์…”๋„ˆ๋ฆฌ (Dictionary - dict)
    • ํŠน์ง•: ํ‚ค(Key)์™€ ๊ฐ’(Value)์˜ ์Œ์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ์ปฌ๋ ‰์…˜. ํ‚ค๋Š” ๊ณ ์œ ํ•˜๊ณ  ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ(hashable) ๊ฐ’์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (์ฃผ๋กœ ๋ฌธ์ž์—ด, ์ˆซ์ž, ํŠœํ”Œ ์‚ฌ์šฉ). ๊ฐ’์€ ์–ด๋–ค ํƒ€์ž…์ด๋“  ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. Python 3.7+ ๋ถ€ํ„ฐ๋Š” ์ž…๋ ฅ ์ˆœ์„œ๊ฐ€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.
    • ๋™์ž‘: ํ‚ค๋ฅผ ํ†ตํ•ด ๊ฐ’์— ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ์ ‘๊ทผ, ์ถ”๊ฐ€, ์ˆ˜์ •, ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (ํ•ด์‹œ ํ…Œ์ด๋ธ” ๊ธฐ๋ฐ˜).
    • ์šฉ๋„: ํ‚ค๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฐพ์•„์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ ๊ฐ„์˜ ์—ฐ๊ด€ ๊ด€๊ณ„๋ฅผ ํ‘œํ˜„ํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์„ธํŠธ (Set - set)
    • ํŠน์ง•: ์ˆœ์„œ๊ฐ€ ์—†๊ณ , ์ค‘๋ณต๋œ ๊ฐ’์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” ์ปฌ๋ ‰์…˜. ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ(mutable) ์ž๋ฃŒ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.
    • ๋™์ž‘: ์š”์†Œ์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ฉ์ง‘ํ•ฉ(|), ๊ต์ง‘ํ•ฉ(&), ์ฐจ์ง‘ํ•ฉ(-) ๋“ฑ ์ง‘ํ•ฉ ์—ฐ์‚ฐ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
    • ์šฉ๋„: ์ค‘๋ณต ์ œ๊ฑฐ, ๋ฉค๋ฒ„์‹ญ ํ…Œ์ŠคํŠธ, ์ง‘ํ•ฉ ์—ฐ์‚ฐ์— ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ํ”„๋กœ์ฆŒ์…‹ (Frozenset - frozenset)
    • ํŠน์ง•: ์„ธํŠธ์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ(immutable) ๋ฒ„์ „์ž…๋‹ˆ๋‹ค.
    • ๋™์ž‘: ์ƒ์„ฑ ํ›„์—๋Š” ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ๋”•์…”๋„ˆ๋ฆฌ์˜ ํ‚ค๋‚˜ ๋‹ค๋ฅธ ์„ธํŠธ์˜ ์š”์†Œ๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์šฉ๋„: ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ์ง‘ํ•ฉ์ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜, ๋”•์…”๋„ˆ๋ฆฌ ํ‚ค ๋“ฑ์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ ์“ฐ์ž…๋‹ˆ๋‹ค.

์ด ์™ธ์—๋„ collections ๋ชจ๋“ˆ์—์„œ deque, Counter, defaultdict ๋“ฑ ๋” ์ „๋ฌธ์ ์ธ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

2. ์ œ๋„ˆ๋ ˆ์ดํ„ฐ (Generators)โ€‹

์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ(iterator)๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฐ„๋‹จํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฐ’์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜๋Š” ๋Œ€์‹ , ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ’์„ ํ•˜๋‚˜์”ฉ ์ƒ์„ฑ(yield)ํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:
    1. ํ•จ์ˆ˜ ๋‚ด์—์„œ yield ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
    2. ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ฆ‰์‹œ ์‹คํ–‰๋˜์ง€ ์•Š๊ณ  ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ๊ฐ์ฒด(์ดํ„ฐ๋ ˆ์ดํ„ฐ)๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    3. next() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ for ๋ฃจํ”„ ๋“ฑ์—์„œ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•จ์ˆ˜ ๋‚ด๋ถ€ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋‹ค๊ฐ€ yield ๋ฌธ์„ ๋งŒ๋‚ฉ๋‹ˆ๋‹ค.
    4. yield๋Š” ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ํ•จ์ˆ˜์˜ ์‹คํ–‰์„ ์ผ์‹œ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜์˜ ๋ชจ๋“  ์ƒํƒœ(์ง€์—ญ ๋ณ€์ˆ˜ ๋“ฑ)๋Š” ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.
    5. ๋‹ค์‹œ next()๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ์ค‘์ง€๋œ ์ง€์  ๋‹ค์Œ๋ถ€ํ„ฐ ์‹คํ–‰์„ ์žฌ๊ฐœํ•ฉ๋‹ˆ๋‹ค.
    6. ํ•จ์ˆ˜ ์‹คํ–‰์ด ๋๋‚˜๊ฑฐ๋‚˜ return ๋ฌธ์„ ๋งŒ๋‚˜๋ฉด StopIteration ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ง• ๋ฐ ์žฅ์ :
    • ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ: ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋ชจ๋“  ๊ฐ’์„ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ์‹œ์ ์— ํ•˜๋‚˜์”ฉ ์ƒ์„ฑํ•˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ๋งค์šฐ ์ ์Šต๋‹ˆ๋‹ค.
    • ์ง€์—ฐ ํ‰๊ฐ€ (Lazy Evaluation): ์‹ค์ œ ๊ฐ’์ด ํ•„์š”ํ•œ ์‹œ์ ๊นŒ์ง€ ๊ณ„์‚ฐ์„ ๋ฏธ๋ฃน๋‹ˆ๋‹ค.
    • ๊ฐ„๊ฒฐํ•œ ์ฝ”๋“œ: ๋ณต์žกํ•œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ ํด๋ž˜์Šค(__iter__, __next__ ๊ตฌํ˜„)๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋ฌดํ•œ ์‹œํ€€์Šค ์ƒ์„ฑ ๊ฐ€๋Šฅ: ๋ฉ”๋ชจ๋ฆฌ ์ œ์•ฝ ์—†์ด ๋ฌดํ•œํžˆ ๊ฐ’์„ ์ƒ์„ฑํ•˜๋Š” ์‹œํ€€์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
def count_up_to(n):
i = 1
while i <= n:
yield i # ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์—ฌ๊ธฐ์„œ ์ž ์‹œ ๋ฉˆ์ถค
i += 1

# ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ๊ฐ์ฒด ์ƒ์„ฑ
counter = count_up_to(3)

print(next(counter)) # ์ถœ๋ ฅ: 1 // ์—ฌ๊ธฐ์„œ ์ž ์‹œ ๋ฉˆ์ถค

# ์—ฌ๊ธฐ์„œ ์•„๋ฌด๋Ÿฐ ์ง“์„ ํ•ด๋„ 2,3์ด ์ถœ๋ ฅ๋˜์ง€ ์•Š์Œ
print(next(counter)) # ์ถœ๋ ฅ: 2

# ์—ฌ๊ธฐ์„œ ์•„๋ฌด๋Ÿฐ ์ง“์„ ํ•ด๋„ 3์ด ์ถœ๋ ฅ๋˜์ง€ ์•Š์Œ
print(next(counter)) # ์ถœ๋ ฅ: 3 ์ด๋ ‡๊ฒŒ ์ง์ ‘ ํ˜ธ์ถœ์„ ํ•ด์•ผ 3์ด ์ถœ๋ ฅ๋จ
# ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฑฐ๊ณ , ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ,
# ๋‹น์—ฐํžˆ ์‹ค์ œ ๊ฐ’์ด ํ•„์š”ํ•œ ์‹œ์ ๊นŒ์ง€ ๊ณ„์‚ฐ์„ ๋ฏธ๋ฃจ๋Š” ๊ฑฐ๊ณ , ๋ฌดํ•œ ์‹œํ€€์Šค ์ƒ์„ฑ๋„ ๊ฐ€๋Šฅํ•จ(์ถœ๋ ฅํ•˜์ง€ ์•Š์œผ๋‹ˆ๊นŒ)
# ์‚ฌ์šฉ๋„ ๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ณ  ์‰ฌ์›€
# print(next(counter)) # ์—ฌ๊ธฐ์„œ StopIteration ์˜ˆ์™ธ ๋ฐœ์ƒ

์‹ค๋ฌด์—์„œ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ์‚ฌ์šฉ ์˜ˆ์‹œโ€‹

from typing import AsyncGenerator

from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine

from .config import settings

engine = create_async_engine(settings.DATABASE_URL, echo=True, future=True)

AsyncSessionLocal = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)


async def get_session() -> AsyncGenerator[AsyncSession, None]:
async with AsyncSessionLocal() as session:
try:
yield session
except Exception:
await session.rollback()
raise

์„ธ์…˜ ์ œ๊ณต (Yield):

yield session: get_session ํ•จ์ˆ˜์˜ ์‹คํ–‰์ด ์—ฌ๊ธฐ์„œ ์ผ์‹œ ์ค‘์ง€๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  async with๋ฅผ ํ†ตํ•ด ์–ป์€ session ๊ฐ์ฒด๊ฐ€ get_session ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ์ชฝ(์˜ˆ: ์›น ์š”์ฒญ ํ•ธ๋“ค๋Ÿฌ)์œผ๋กœ **๋ฐ˜ํ™˜(์ œ๊ณต)**๋ฉ๋‹ˆ๋‹ค. ํ˜ธ์ถœํ•œ ์ชฝ์—์„œ๋Š” ์ด session ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฟผ๋ฆฌ, ์ถ”๊ฐ€, ์ˆ˜์ •, ์‚ญ์ œ ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

3. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ (Decorators)โ€‹

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๊ธฐ์กด ํ•จ์ˆ˜๋‚˜ ๋ฉ”์†Œ๋“œ์˜ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•˜์ง€ ์•Š์œผ๋ฉด์„œ, ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ๋ง๋ถ™์ด๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. @ ๊ธฐํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:
    1. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„์„œ, ์ˆ˜์ •๋œ ๋˜๋Š” ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ (๊ณ ์ฐจ ํ•จ์ˆ˜)์ž…๋‹ˆ๋‹ค.
    2. @my_decorator๋ฅผ ํ•จ์ˆ˜ func ์œ„์— ์“ฐ๋ฉด, ํŒŒ์ด์ฌ์€ ๋‚ด๋ถ€์ ์œผ๋กœ func = my_decorator(func) ์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
      • ์ฆ‰, ์›๋ž˜ ํ•จ์ˆ˜ func๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜ my_decorator์— ์ „๋‹ฌ๋˜๊ณ ,
      • ๊ทธ ๋ฐ˜ํ™˜๊ฐ’(์ฃผ๋กœ ๋‚ด๋ถ€ wrapper ํ•จ์ˆ˜)์ด ๋‹ค์‹œ func๋ผ๋Š” ์ด๋ฆ„์— ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.
    3. ์ดํ›„ func()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์‹ค์ œ๋กœ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
      • ์ด ๋ฐ˜ํ™˜๋œ ํ•จ์ˆ˜๋Š” ๋ณดํ†ต ๋‚ด๋ถ€์—์„œ ์›๋ณธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ ์ถ”๊ฐ€์ ์ธ ๋กœ์ง(์ „์ฒ˜๋ฆฌ, ํ›„์ฒ˜๋ฆฌ)์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ง• ๋ฐ ์šฉ๋„:
    • ์ฝ”๋“œ ์ค‘๋ณต ๊ฐ์†Œ: ๋กœ๊น…, ์ ‘๊ทผ ์ œ์–ด, ์„ฑ๋Šฅ ์ธก์ •, ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ ๋“ฑ ์—ฌ๋Ÿฌ ํ•จ์ˆ˜์— ๊ณตํ†ต์ ์œผ๋กœ ์ ์šฉ๋  ๋กœ์ง์„ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ๋งŒ๋“ค์–ด ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ: ํ•จ์ˆ˜์˜ ํ•ต์‹ฌ ๋กœ์ง๊ณผ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๋” ๊น”๋”ํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
    • ์œ ์ง€๋ณด์ˆ˜ ์šฉ์ด์„ฑ: ๊ณตํ†ต ๋กœ์ง ๋ณ€๊ฒฝ ์‹œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
import time

def measure_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs) # ์›๋ณธ ํ•จ์ˆ˜ ํ˜ธ์ถœ
end_time = time.time()
print(f"Function {func.__name__} took {end_time - start_time:.4f} seconds")
return result
return wrapper # ๋‚ด๋ถ€ ํ•จ์ˆ˜(wrapper)๋ฅผ ๋ฐ˜ํ™˜

@measure_time # ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ ์šฉ
def slow_function(n):
time.sleep(n)
return "Done"

slow_function(1) # ์ถœ๋ ฅ: Function slow_function took 1.xxxx seconds

# ๋‚ด๋ถ€์—์„œ๋Š” ์•„๋ž˜ ์ฒ˜๋Ÿผ ๋™์ž‘ํ•จ
slow_function = measure_time(slow_function)

4. ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ (Asyncio)โ€‹

asyncio๋Š” ํŒŒ์ด์ฌ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, async/await ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ I/O ๋ฐ”์šด๋“œ(๋„คํŠธ์›Œํฌ ํ†ต์‹ , ํŒŒ์ผ ์ฝ๊ธฐ/์“ฐ๊ธฐ ๋“ฑ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ๋งŽ์€ ์ž‘์—…) ์ž‘์—…์—์„œ ๋†’์€ ์„ฑ๋Šฅ์„ ๋ฐœํœ˜ํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹ (์ด๋ฒคํŠธ ๋ฃจํ”„ ๊ธฐ๋ฐ˜):
    1. async def๋กœ ์ •์˜๋œ ํ•จ์ˆ˜๋Š” ์ฝ”๋ฃจํ‹ด(coroutine) ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋ฃจํ‹ด์€ ์‹คํ–‰์„ ์ค‘๊ฐ„์— ๋ฉˆ์ถ”๊ณ  ๋‹ค๋ฅธ ์ฝ”๋ฃจํ‹ด์—๊ฒŒ ์ œ์–ด๊ถŒ์„ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ๋Š” ํŠน๋ณ„ํ•œ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
    2. await ํ‚ค์›Œ๋“œ๋Š” ์ฝ”๋ฃจํ‹ด ๋‚ด์—์„œ ๋‹ค๋ฅธ ์ฝ”๋ฃจํ‹ด์ด๋‚˜ awaitable ๊ฐ์ฒด(์˜ˆ: asyncio.sleep, I/O ์ž‘์—…)์˜ ์™„๋ฃŒ๋ฅผ ๊ธฐ๋‹ค๋ฆด ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. await๋ฅผ ๋งŒ๋‚˜๋ฉด ํ˜„์žฌ ์ฝ”๋ฃจํ‹ด์˜ ์‹คํ–‰์€ ์ผ์‹œ ์ค‘์ง€๋˜๊ณ , ํ”„๋กœ๊ทธ๋žจ์˜ ์ œ์–ด๊ถŒ์€ **์ด๋ฒคํŠธ ๋ฃจํ”„(event loop)**๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.
    3. ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ํ˜„์žฌ ๋Œ€๊ธฐ ์ค‘์ธ ๋‹ค๋ฅธ ์ž‘์—…(๋‹ค๋ฅธ ์ฝ”๋ฃจํ‹ด)์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    4. await ํ–ˆ๋˜ ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด (์˜ˆ: ๋„คํŠธ์›Œํฌ ์‘๋‹ต ๋„์ฐฉ), ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ํ•ด๋‹น ์ง€์ ์—์„œ ์ค‘์ง€๋˜์—ˆ๋˜ ์ฝ”๋ฃจํ‹ด์˜ ์‹คํ–‰์„ ๋‹ค์‹œ ์žฌ๊ฐœํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ง• ๋ฐ ์žฅ์ :
    • ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ๋™์‹œ์„ฑ: ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋‚˜ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ๋‹จ์ผ ์Šค๋ ˆ๋“œ ๋‚ด์—์„œ ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค (์ฃผ๋กœ I/O ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ํ™œ์šฉ). GIL์˜ ์ œ์•ฝ์„ ๋ฐ›์ง€ ์•Š๊ณ  I/O ์ž‘์—…์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋†’์€ I/O ์ฒ˜๋ฆฌ๋Ÿ‰: ๋„คํŠธ์›Œํฌ ์„œ๋ฒ„, ์›น ํด๋ผ์ด์–ธํŠธ ๋“ฑ ๋™์‹œ์— ๋งŽ์€ I/O ์—ฐ๊ฒฐ์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
    • ๋ช…์‹œ์  ๋น„๋™๊ธฐ: async/await ํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ์˜ ์–ด๋–ค ๋ถ€๋ถ„์ด ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋™์ž‘ํ•˜๊ณ  ๋Œ€๊ธฐํ•˜๋Š”์ง€ ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
import asyncio

async def say_after(delay, what):
await asyncio.sleep(delay) # delay ์ดˆ ๋™์•ˆ ๋Œ€๊ธฐ
print(what)

async def main():
print("Started")
task1 = asyncio.create_task(say_after(1, 'hello')) # ์ž‘์—…์„ ์ด๋ฒคํŠธ ๋ฃจํ”„์— ๋“ฑ๋ก
task2 = asyncio.create_task(say_after(2, 'world'))

await task1 # task1 ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ
await task2 # task2 ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ
print("Finished")

# Python 3.7+
asyncio.run(main())
# ์ถœ๋ ฅ ์ˆœ์„œ:
# Started
# (1์ดˆ ํ›„) hello
# (1์ดˆ ๋” ํ›„) world
# Finished

5. GIL (Global Interpreter Lock)โ€‹

GIL์€ ์ „์—ญ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ž ๊ธˆ(Global Interpreter Lock)์˜ ์•ฝ์ž๋กœ, CPython(ํŒŒ์ด์ฌ ํ‘œ์ค€ ๊ตฌํ˜„์ฒด)์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ํŒŒ์ด์ฌ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰๋Š” ๋ฎคํ…์Šค(mutex, ์ƒํ˜ธ ๋ฐฐ์ œ ์ž ๊ธˆ)์ž…๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:
    • CPython ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋Š” ์‹คํ–‰๋  ๋•Œ GIL์„ ํš๋“ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • ํ•œ ๋ฒˆ์— ์˜ค์ง ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ์ด GIL์„ ๋ณด์œ ํ•˜๊ณ  ํŒŒ์ด์ฌ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์ผ์ • ์‹œ๊ฐ„ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜, ํŠนํžˆ I/O ์ž‘์—…(ํŒŒ์ผ ์ฝ๊ธฐ/์“ฐ๊ธฐ, ๋„คํŠธ์›Œํฌ ํ†ต์‹  ๋“ฑ)์„ ๋งŒ๋‚˜๋ฉด ํ•ด๋‹น ์Šค๋ ˆ๋“œ๋Š” GIL์„ ๋ฐฉ์ถœ(release)ํ•˜์—ฌ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰๋  ๊ธฐํšŒ๋ฅผ ์ค๋‹ˆ๋‹ค.
  • ์˜ํ–ฅ:
    • CPU ๋ฐ”์šด๋“œ ์ž‘์—…: ๊ณ„์‚ฐ ์ง‘์•ฝ์ ์ธ ์ž‘์—…์˜ ๊ฒฝ์šฐ, ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ”„๋กœ์„ธ์„œ๊ฐ€ ์žˆ๋”๋ผ๋„ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ์ง„์ •ํ•œ ๋ณ‘๋ ฌ ์‹คํ–‰์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์˜คํžˆ๋ ค ์Šค๋ ˆ๋“œ ๊ฐ„ GIL ํš๋“ ๊ฒฝ์Ÿ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
    • I/O ๋ฐ”์šด๋“œ ์ž‘์—…: ์Šค๋ ˆ๋“œ๊ฐ€ I/O ๋Œ€๊ธฐ ์ค‘์— GIL์„ ๋†“์•„์ฃผ๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ทธ ์‹œ๊ฐ„์— ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์Šค๋ ˆ๋”ฉ์€ I/O ๋ฐ”์šด๋“œ ์ž‘์—…์˜ ๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ์—๋Š” ์—ฌ์ „ํžˆ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.
  • ์™œ ์กด์žฌํ•˜๋Š”๊ฐ€?
    • CPython์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ(ํŠนํžˆ ์ฐธ์กฐ ์นด์šดํŒ…)๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๊ณ  ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
    • C ํ™•์žฅ ๋ชจ๋“ˆ ๊ฐœ๋ฐœ์„ ์šฉ์ดํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค (GIL์ด ์Šค๋ ˆ๋“œ ๊ด€๋ จ ๋ณต์žก์„ฑ์„ ์ผ๋ถ€ ํ•ด๊ฒฐ).
  • ๊ทน๋ณต ๋ฐฉ๋ฒ•:
    • ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ (multiprocessing ๋ชจ๋“ˆ): ๊ฐ ํ”„๋กœ์„ธ์Šค๋Š” ์ž์‹ ๋งŒ์˜ ํŒŒ์ด์ฌ ์ธํ„ฐํ”„๋ฆฌํ„ฐ์™€ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„, ๊ทธ๋ฆฌ๊ณ  ์ž์‹ ๋งŒ์˜ GIL์„ ๊ฐ€์ง€๋ฏ€๋กœ, ์—ฌ๋Ÿฌ CPU ์ฝ”์–ด๋ฅผ ํ™œ์šฉํ•œ ์ง„์ •ํ•œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. CPU ๋ฐ”์šด๋“œ ์ž‘์—…์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
    • Asyncio: ์•ž์„œ ์„ค๋ช…ํ–ˆ๋“ฏ์ด ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ๋‚ด์—์„œ ์ด๋ฒคํŠธ ๋ฃจํ”„๋ฅผ ํ†ตํ•ด I/O ๋ฐ”์šด๋“œ ์ž‘์—…์˜ ๋™์‹œ์„ฑ์„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. GIL ๊ฒฝ์Ÿ์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋‹ค๋ฅธ ํŒŒ์ด์ฌ ๊ตฌํ˜„์ฒด: Jython(JVM ๊ธฐ๋ฐ˜), IronPython(.NET ๊ธฐ๋ฐ˜) ๋“ฑ GIL์ด ์—†๋Š” ๊ตฌํ˜„์ฒด๋„ ์žˆ์ง€๋งŒ, CPython๊ณผ์˜ ํ˜ธํ™˜์„ฑ์ด๋‚˜ ์ƒํƒœ๊ณ„ ํฌ๊ธฐ์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.