-
Efficient python Ch24. 동적인 디폴트 인자 관리법뜯고 또 뜯어보는 컴퓨터/파이썬 (Python) 2021. 7. 31. 13:30반응형
- 우리는 종종 정적으로 정해지지 않은 타입의 값(동적 타입: list, dict 등등)을 함수의 인자의 값으로 써야할 때가 있다. 예를 들어 로그 메시지와 시간을 함께 출력하고 싶다고 하자.
from time import sleep from datetime import datetime def log(message, when=datetime.now()): print(f'{when}: {message}') log("안녕") sleep(0.1) log("다시 안녕")
더보기2021-07-31 13:06:21.846984: 안녕
2021-07-31 13:06:21.846984: 다시 안녕
- 하지만, sleep=0.1 이 호출되었는데도, 시간은 변하지 않고, 그대로 출력되었는데, 이유는 다음과 같다.
- 파이썬에서는 default 인자는 함수가 호출될 때, 함수가 정의된 시점 딱 한번 정의된다. 따라서, 프로그램을 다시 시작하지 않는 한, defualt 인자는 변하지 않는다.
- 따라서 일반적 관례는 default = None 을 지정하고, 실제 동작을 독스트링에 문서화 하는 것이다.
def log(message, when = None): """메시지와 타임스탬프를 로그에 남긴다. Args : message: 출력할 메세지 when: 메시지가 발생한 시각 default 값은 현재 시간이다. """ if when == None: when = datetime.now() print(f'{when}: {message}') log("안녕") sleep(0.1) log("다시 안녕")
더보기2021-07-31 13:16:42.388444: 안녕
2021-07-31 13:16:42.490728: 다시 안녕
다음의 예시로 json 의 데이터를 받고, json 데이터를 load 했을 시, 잘못된 형식이면 비어있는 dict를 반환한다고 가정해보자
import json def decode(data, default = {}): try: return json.loads(data) except ValueError: return default foo = decode("잘못된 데이터") foo["stuff"] = 5 bar = decode("또 잘못된 데이터") bar["meep"] = 1 print("foo",foo) print("bar",bar)
더보기foo {'stuff': 5, 'meep': 1}
bar {'stuff': 5, 'meep': 1}
- 다음과 같이 심각한 오류를 야기할 수 있는데, 우리가 예상한 값은, foo {'stuff': 5} bar {'meep': 1}
- 이런 값이었을 텐데, 값이 공유되었다. 어찌된 일일까??? 그 이유는 앞서 설명했듯이, 파이썬은 함수를 처음 정의 할때, 단 한번만 default값이 평가 되기 때문에, dict 값을 공유하게 되는 것이다. 따라서 이러한 일을 막기 위해서는 다음과 같이 함수인자의 default 값으로 None을 지정하고, 독스트링을 통해 문설화를 시켜주는 것이다.
def decode(data, default = None): """ 문자열로부터 JSON. 데이터를 읽어온다. Args: data: 디코딩할 JSON 데이터 default: 디코딩 실패 시 반환할 값이다. 디폴트 값은 dict 값이다. """ try: return json.loads(data) except ValueError: if default == None: default = {} return default foo = decode("잘못된 데이터") foo["stuff"] = 5 bar = decode("또 잘못된 데이터") bar["meep"] = 1 print("foo",foo) print("bar",bar)
더보기foo {'stuff': 5}
bar {'meep': 1}
- Ch 24. 기억해야 할 내용
- 디폴트 인자 값은 그 인자가 포함된 함수가 정의될때 딱 한번!!! 만 정의 된다. 그로 인해 동적인 값들({},[],/..) 는 이상한 동작을 할 수 있다.
- 동적인 값을 갖리 수 있는 키워드 인자의 디폴트 값을 표현할 때는 None 을 쓸 수 있도록 하자.
반응형'뜯고 또 뜯어보는 컴퓨터 > 파이썬 (Python)' 카테고리의 다른 글
Efficient Python 23. 키워드 인자 사용법 (0) 2021.07.30 Efficient Python 22. 변수위치 인자(*Args) 사용법 (0) 2021.07.30 Effective Python 21. 클로져란 (0) 2021.07.30 Effective python ch20. None보다는 예외를 (0) 2021.07.29