파이썬3 노트

[return] [yield] [yield from]

Jonchann 2018. 12. 15. 17:06

파이썬3.+ 에서 함수를 만들 때 마지막에 return을 적으면 return 뒤에 나오는 값을 반환하고 함수를 끝낸다.


예를 들어, 아래와 같은 함수가 있다고 하자.

def noniter(file: Path):
    datum = []
    with open(file, mode='r', encoding='utf-8') as f:
        csvf = csv.reader(f)
        for line in csvf:
            data = (line[1], tokenize(line[3]))
            datum.append(data)
    return datum

이 함수에 파일 인수를 입력해 실행하면 datum을 반환하고 멈춘다.


하지만 yield는 다르다.

return과 달리 함수가 처리한 결과를 반환하고도 처리할 인수가 남았으면 다시 함수를 돌린다.

예를 들어, 위의 함수는 아래와 같이 적을 수 있다.

def iter(file: Path):
    with open(file, mode='r', encoding='utf-8') as f:
        csvf = csv.reader(f)
        for line in csvf:
            yield line[1], tokenize(line[2])

datum = iter('filename')


코드를 읽어보면 알겠지만 noniter()함수는 함수 안에서 비어있는 리스트를 만들어 for loop으로 append를 해주면서 채운 리스트 하나를 반환하고 끝나지만 아래에 적은 iter()함수는 함수를 돌리는 것 자체로 리스트가 만들어진다.


이젠 yield from에 대해서 생각해보겠다.

일단 아래와 같은 코드가 있다고 하자.

def iter_(file: Path):
    with open(file, mode='r', encoding='utf-8') as f:
        yield from csv.reader(f)

datum = iter_('filename')


함수를 돌리는 것 자체로 datum이 리스트가 되는 것은 yield와 변함 없는 것 같아 보이지만 사실 다르다.

iter()함수에서는 csv파일을 읽어 와 그 중에서 인덱스 1 번과 3 번에 할당되어있는 값을 반환한다.


하지만 yield from은 원하는 인덱스만 선택해서 반환하는 것이 불가능하다. 그냥 파일을 한 줄 한 줄 읽어올 때 마다 통째로 반환하기 때문이다.


따라서 별로 골라 담을 필요 없이 통째로 리스트로 만들고 싶을 때에는 yield보다 yield from을 사용하는 것이 낫다.