728x90

디폴트 인자 값으로 None을 사용하는 것은 인자가 가변적인 경우 특히 중요하다.

JSON 데이터로 인코딩된 값을 읽으려고하는데 데이터 디코딩에 실패하면 기본값으로 빈 dict 를 반환하고싶다고 가정해보자.

 

import json
def decode(data, default={}):
	try:
    	return json.loads(data)
    except ValueError:
    	return default

 

이 코드는 몇가지 문제가 있다.

 

default 값이 모듈을 로드하는 시점에 단 한번만 평가되기 때문에 default에 지정된 dict 가 decode 함수 호출에 모두 공유된다.

이로인해 매우 놀라운 결과가 나타난다..

 

 

foo = decode('error data')
foo['A'] = 10

bar = decode('error data2')
bar['B'] = 20
print('foo', foo)
print('bar', bar)
Foo: {'A': 10, 'B': 20}
Bar: {'A': 10, 'B': 20}

 

 

한쪽 dict를 변경하면 다른쪽 dict 도 변경 되는것 처럼 보인다. foo 와 bar 모두 default 파라미터가 같기 때문이다.

둘은 모두 동일한 딕셔너리 객체다.

 

이 문제를 해결하기 위해서는 함수에 있는 키워드 인자를 default value 로 None 을 지정하고 function 의 doc string 에 동작 방식을 서술한다.

 

def decode(data, default=None):
    """
    문자열로 부터 JSON 데이터를 읽어온다.

    Args:
        data: decodeing json data
        default: decodeing faile return value
            default is empty dict
    """

    try:
        return json.loads(data)
    except ValueError:
        if default is None:
            default = {}
        return default

 

Foo: {'A': 10}
Bar: {'B': 20}

 

라는 결과를 얻을수 있다.

728x90

'Python > python - pythonic' 카테고리의 다른 글

Decorator  (0) 2020.12.07
데코레이터를 이해하기전 알아야 할것들  (0) 2020.12.06
벡터 클래스의 부활  (0) 2020.12.04
WeakValueDictionary 촌극  (0) 2020.12.04
약한참조  (2) 2020.12.02