def hello():
print("Hello")
def deco(fn):
def deco_hello():
print("*" * 20)
fn()
print("*" * 20)
return deco_hello
deco_hello = deco(hello)
deco_hello()
함수 자체를 수정하지 않고 기능 추가 가능
데코레이터라고 선언하고 사용하는 방법
(아래에서는 deco라는 이름의 함수를 찾아서 적용해 줌 - 이름 상관없음)
@deco
def hello2():
print("hello 2")
예시)
@property
property는 파이썬에 미리 정의되어 있는 데코레이터 객체, 내장(built-in) 데코레이터
-> 항상 클로저일 필요는 없음
클로저
├─ 상태를 가진 함수
├─ 함수 + 환경
└─ 구현 기법
데코레이터
├─ callable → callable
├─ 함수 교체 메커니즘
└─ 목적/패턴
클래스
├─ 상태를 가진 객체
└─ 데코레이터 구현 수단 중 하나
print 대신 파일에
import logging
logging.basicConfig(filename="mylog.txt", level=logging.INFO)
def hap(a, b):
ret = a + b
logging.info(f"input: {a} {b}, output={ret}")
return ret
result = hap(3, 4)
디렉토리에 mylog.txt 로깅 파일 생성

운영체제는 프로그램들이 마음껏 실핼될 수 있도록 '놀이터'와 같은 공간을 제공 --> 이것이 프로세스
놀이터에 있는 플레이어를 --> 스레드
스레드가 프로세스를 벗어나려 하변 운영체제에 의해 종료됨
같은 프로세스에 있는 자원은 스레드들이 공유
운영체제가 동시에 실행되는 여러 프로그램을 관리하는 작업을 스케줄링 (스케쥴의 단위가 스레드)
프로그램 작성 시 여러개의 스레드 사용 - 멀티 스레드
https://docs.python.org/3/library/threading.html
import threading
import time
class Worker(threading.Thread):
def __init__(self, name):
super().__init__()
self.name = name # 스레드 이름 지정
def run(self):
print("sub thread start ", threading.current_thread().name)
time.sleep(3)
print("sub thread end ", threading.current_thread().name)
print("main thread start")
for i in range(5):
name = "thread {}".format(i)
t = Worker(name) # sub thread 생성
t.start() # sub thread의 run 메서드를 호출
print("main thread end")
main thread start
sub thread start thread 0
sub thread start thread 1
sub thread start thread 2
sub thread start thread 3
sub thread start thread 4
main thread end
sub thread end thread 0
sub thread end thread 1
sub thread end thread 4
sub thread end thread 3
sub thread end thread 2
run()을 새 스레드에서 실행
메인 스레드는 기다리지 않음
그래서 먼저 출력
위 예제 코드는 concurrency 동시성
파이썬은 한 순간에 하나의 스레드만 Python bytecode 실행 가능
(GIL - Global Interpreter Lock)
그러나
multiprocessing 사용 시에는 진짜 병렬 실행
from multiprocessing import Process
Daemon Thread는 메인 스레드가 종료될 때 자신의 실행 상태와 상관없이 종료되는 서브 스레드
파이썬 threading 모듈에서 데몬 스레드의 생성은 daemon 속성을 True로 변경하면 됨
import threading
import time
class Worker(threading.Thread):
def __init__(self, name):
super().__init__()
self.name = name # 스레드 이름 지정
def run(self):
print("sub thread start ", threading.current_thread().name)
time.sleep(3)
print("sub thread end ", threading.current_thread().name)
print("main thread start")
for i in range(5):
name = "thread {}".format(i)
t = Worker(name) # sub thread 생성
t.daemon = True # main thread가 종료되면 sub thread도 종료
t.start() # sub thread의 run 메서드를 호출
print("main thread end")
main thread start
sub thread start thread 0
sub thread start thread 1
sub thread start thread 2
sub thread start thread 3
main thread end