Skip to content

Latest commit

Β 

History

History
126 lines (97 loc) Β· 3.32 KB

File metadata and controls

126 lines (97 loc) Β· 3.32 KB

38. κ°„λ‹¨ν•œ μΈν„°νŽ˜μ΄μŠ€μ˜ 경우 클래슀 λŒ€μ‹  ν•¨μˆ˜λ₯Ό 받아라

1. ν›…(hook)

  • API κ°€ μ‹€ν–‰λ˜λŠ” κ³Όμ •μ—μ„œ μ „λ‹¬ν•œ ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λŠ” 경우
  • sort λ©”μ†Œλ“œμ—μ„œ key λ₯Ό ν›…μœΌλ‘œ len λ‚΄μž₯ ν•¨μˆ˜λ₯Ό μ „λ‹¬ν•˜λŠ” 예제
names = ['μ†Œν¬λΌν…ŒμŠ€', 'μ•„λ₯΄ν‚€λ©”λ°μŠ€', 'ν”ŒλΌν†€', 'μ•„λ¦¬μŠ€ν† ν…”λ ˆμŠ€']
names.sort(key=len)
print(names)

>>>
['ν”ŒλΌν†€', 'μ†Œν¬λΌν…ŒμŠ€', 'μ•„λ₯΄ν‚€λ©”λ°μŠ€', 'μ•„λ¦¬μŠ€ν† ν…”λ ˆμŠ€']
  • defaultdict λ₯Ό μ‚¬μš©ν•˜μ—¬ ν›… μ‚¬μš©ν•˜λŠ” 예제
    • ν›… ν•¨μˆ˜: log_missing
from collections import defaultdict

def log_missing():
    print('ν‚€ 좔가됨')
    return 0

current = {'초둝': 12, 'νŒŒλž‘': 3}
increments = [
    ('λΉ¨κ°•', 5),
    ('νŒŒλž‘', 17),
    ('μ£Όν™©', 9),
]
result = defaultdict(log_missing, current)
print('이전:', dict(result))
for key, amount in increments:
    result[key] += amount
print('이후:', dict(result))

>>>
이전: {'초둝': 12, 'νŒŒλž‘': 3}
ν‚€ 좔가됨
ν‚€ 좔가됨
이후: {'초둝': 12, 'νŒŒλž‘': 20, 'λΉ¨κ°•': 5, 'μ£Όν™©': 9}

2. ν›… ν•¨μˆ˜μ—μ„œ μƒνƒœλ₯Ό μ²˜λ¦¬ν•  수 μžˆλ„λ‘ ν™•μž₯ν•œ 예제

  • missing ν›… ν•¨μˆ˜μ— added_count λ³€μˆ˜μ— μƒνƒœλ₯Ό 기둝
def increment_with_report(current, increments):
    added_count = 0

    def missing():
        nonlocal added_count  # μƒνƒœκ°€ μžˆλŠ” ν΄λ‘œμ €
        added_count += 1
        return 0

    result = defaultdict(missing, current)
    for key, amount in increments:
        result[key] += amount

    return result, added_count

result, count = increment_with_report(current, increments)
assert count == 2
  • κ°„λ‹¨ν•œ 클래슀둜 μƒνƒœλ₯Ό κ΄€λ¦¬ν•˜λŠ” 예제
class CountMissing:
    def __init__(self):
        self.added = 0
        
    def missing(self):
        self.added += 1
        return 0

counter = CountMissing()
result = defaultdict(counter.missing, current)  # λ©”μ„œλ“œ μ°Έμ‘°
for key, amount in increments:
    result[key] += amount
assert counter.added == 2
  • 헬퍼 클래슀둜 μƒνƒœκ°€ μžˆλŠ” ν΄λ‘œμ €μ™€ 같은 λ™μž‘ κ΅¬ν˜„μ΄ ν•¨μˆ˜ μ‚¬μš©ν•œ κ΅¬ν˜„λ³΄λ‹€ 깔끔함
  • κ·ΈλŸ¬λ‚˜ 클래슀만 보면 ν•΄λ‹Ή 클래슀 μ •μ˜ λͺ©μ μ΄ λ“œλŸ¬λ‚˜μ§€ μ•ŠμŒ
    • λˆ„κ°€ λ§Œλ“€μ§€?
    • λˆ„κ°€ ν˜ΈμΆœν•˜μ§€?
    • μΆ”ν›„ 곡개 λ©”μ†Œλ“œκ°€ 더 좔가될 κ°€λŠ₯성은?
    • ...
  • __call__ νŠΉλ³„ λ©”μ†Œλ“œ μ •μ˜ν•œ 예제
class BetterCountMissing:
    def __init__(self):
        self.added = 0
        
    def __call__(self):
        self.added += 1
        return 0
        
counter = BetterCountMissing()
assert counter() == 0
assert callable(counter)
  • __call__, callable 객체
    • 객체λ₯Ό ν•¨μˆ˜μ²˜λŸΌ 호좜 κ°€λŠ₯함
    • __call__ 이 μ •μ˜λœ 클래슀 μΈμŠ€ν„΄μŠ€μ— λŒ€ν•΄ callable λ‚΄μž₯ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ True λ°˜ν™˜λ¨
counter = BetterCountMissing()
result = defaultdict(counter, current)  # __call__에 μ˜μ‘΄ν•¨
for key, amount in increments:
    result[key] += amount
assert counter.added == 2

3. 정리

  • μ—¬λŸ¬ μ»΄ν¬λ„ŒνŠΈ 사이 κ°„λ‹¨ν•œ μΈν„°νŽ˜μ΄μŠ€κ°€ ν•„μš”ν•  λ•ŒλŠ” 클래슀 μΈμŠ€ν„΄μŠ€ν™”ν•˜λŠ” λŒ€μ‹  ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ”κ²Œ 이득
  • callable 객체λ₯Ό μ‚¬μš©ν•˜λ©΄ ν•¨μˆ˜μ²˜λŸΌ 호좜 κ°€λŠ₯
  • μƒνƒœλ₯Ό κ΄€λ¦¬ν•˜λŠ” ν•¨μˆ˜κ°€ ν•„μš”ν•œ 경우 callable 객체λ₯Ό μ‚¬μš©ν•΄μ•Ό ν• μ§€λ₯Ό κ³ λ―Όν•  것