본문 바로가기
개발/파이썬

파이썬 리턴값 편리 기능

by esstory 2018. 11. 18.

파이썬에는 몫과 나머지를 한번에 구하는 dibmod 함수가 있다. 

a, b = divmod(123, 5)

 

여기서 특이한 점은 함수의 리턴이 마치 2개가 되는 것처럼 표현되어 a, b 두 변수에 각각 할당 된다는 점

 

실제 divmod 의 리턴값은 tuple 하나이며 아래와 같이 확인 해 볼 수 있다. 

a = divmod(123,5)
type(a)
Out[6]: tuple
print(a)
(24, 3)

 

단 파이썬에서는 tuple 에 한해 패킹과 언패킹을 손쉽게 해 줘서 처음 예제처럼 a, b 변수에 튜플을 분리해서 값을 넣어주는 식이다. 

 

함수는 실제 구현하고자 하는 목적을 달성하기 위해 대부분 어떤 값을 리턴하는 경우가 많다 

대부분의 언어에서는 리턴값이 하나이기 때문에, 하나의 리턴값으로 함수의 성공을 리턴할 지, 결과 값을 리턴할 지(결과가 하나만 있을 경우), 다양한 케이스가 있기 마련이다.

HRESULT MyFunction([in] long aLongValue, [out,retval] short *outValue);

예전에 C++ 을 이용해 COM 개발을 할 때는 위와 같이 엄격한 룰에 의해 

리턴되는 값은 반드시 HRESULT 로 성공/실패 여부로만 사용하고, 함수의 인자와 결과값으로 넘겨 받을 데이터 등은 IN/OUT 으로 기술했었다. 

 

파이썬 함수의 편리한 리턴처리를 이용해서 함수 만드는 룰을 잘 만들어보면 좋겠다는 생각이 들었다 

아래는 함수의 리턴만으로 성공/실패 여부와 함수에서 생성한 결과 데이터를 한번에 리턴한다.

 # in_NumOrMoney '1' 순매수량 '2' 추정금액(백만)
    def Request(self, code, rqCnt, in_NumOrMoney):
        self.objRq.SetInputValue(0, code)
        self.objRq.SetInputValue(6, in_NumOrMoney)  # '1' 순매수량 '2' 추정금액(백만)
 
        ret7254 = []
 
        while True:
            # 조회 제한 체크 - 시세 연속 조회 제한회피를 위한 sleep
            waitRqLimit(1)
            self.objRq.BlockRequest()
            # 현재가 통신 및 통신 에러 처리
            rqStatus = self.objRq.GetDibStatus()
            if rqStatus != 0:
                return (False, ret7254)
 
            cnt = self.objRq.GetHeaderValue(1)
 
            for i in range(cnt):
                item = {}
                fixed = self.objRq.GetDataValue(18, i)
                # 잠정치는 일단 버린다
                if (fixed == ord('0')):
                    continue
 
                item['거래량'] = self.objRq.GetDataValue(17, i)
                item['일자'] = self.objRq.GetDataValue(0, i)
                item['종가'] = self.objRq.GetDataValue(14, i)
                item['개인'] = self.objRq.GetDataValue(1, i)
                item['외국인'] = self.objRq.GetDataValue(2, i)
                item['기관'] = self.objRq.GetDataValue(3, i)
                item['대비율'] = self.objRq.GetDataValue(16, i)
                ret7254.append(item)
 
                if (len(ret7254) >= rqCnt):
                    break
                #end of for
 
            # 연속 조회 가능 체크
            if self.objRq.Continue == False:
                break
            # 데이터 개수 확인
            if (len(ret7254) >= rqCnt):
                break
            #end of while
 
 
        return (True, ret7254)

 

위 내용 중 아래 코드가 오늘 하고 싶은 얘기의 핵심 ^^

return (True, ret7254)

함수는 1번째 리턴값으로 성공 실패 여부를, 2번째 리턴값으로 함수에서 생성한 결과 데이터를 넘긴다.

ret, ret7254 = obj7254.Request('A005930', 100, ord('1'))

사용하는 곳에서는 divmod 처럼 변수 2개에 값을 넘겨 받아 해당 처리를 하면 되는 식

 

물론 함수의 인자값과 리턴값은 작성하는 사람들 편한대로 하면 된다 

함수의 성공/실패 여부와 인자의 전달, 리턴값의 수신 등을 고려 할 때 한가지 방법으로만 읽어 주시길 ~

 

 

댓글