Python 3에서 generator에 type hint를 적용하기
Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.
Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.
아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.
How to type hint a generator in Python 3?
Python 3에서 generator에 type hint를 적용하는 방법은?
문제 내용
According to PEP-484, we should be able to type hinting a generator function as follows:
PEP-484에 따르면 generator 함수를 type hint하는 방법은 다음과 같다고 한다:
from typing import Generator
def generate() -> Generator[int, None, None]:
for i in range(10):
yield i
for i in generate():
print(i)
However, the list comprehension gives the following error in PyCharm.
그러나, 이를 리스트 내포로 구현하면 PyCharm에서 다음과 같은 오류가 발생한다.
Expected 'collections.Iterable', got 'Generator[int, None, None]' instead less... (⌘F1)
Any idea why PyCharm is considering this as error?
PyCharm이 이를 오류로 처리하는 이유가 무엇인지 아시나요?
A few clarification after reading some answers. I am using PyCharm Community Edition 2016.3.2 (the latest version) and have imported the typing.Generator
(updated in the code). The above code runs just fine, but PyCharm considers this an error:
몇 가지 답변을 읽고 나서 몇 가지 설명을 추가합니다. 나는 PyCharm Community Edition 2016.3.2(최신 버전)을 사용하고 있으며 typing.Generator를 가져왔다. 위의 코드는 아주 잘 작동하지만 PyCharm은 이를 오류로 처리합니다.
So, I'm wondering if this is actually an error or an unsupported feature in PyCharm.
그래서, 이게 실제로 오류인지 아니면 PyCharm에서 지원하지 않는 기능인지 궁금합니다.
높은 점수를 받은 Solution
You need to import the typing
module. As per docs:
typing 모듈을 import해야 합니다. 문서에 따르면:
The return type of generator functions can be annotated by the generic type
Generator[yield_type, send_type, return_type]
provided bytyping.py
module
Generator 함수의 반환 타입은 typing.py 모듈에서 제공하는 Generator[yield_type, send_type, return_type] 제네릭 타입으로 주석으로 작성할 수 있습니다.
Try this way instead:
다음처럼 해보세요:
from typing import Generator
def generate() -> Generator[int, None, None]:
for i in range(10):
yield i
The above will have the desired result:
위 코드는 원하는 결과를 얻을 수 있습니다:
l = [i for i in generate()]
Output:
출력:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
As pointed out in the comments, you might not use the last version of PyCharm. Try switching to version 2016.3.2 and you might be fine. Unfortunately this is a well-known bug, as per @AshwiniChaudhary comment.
댓글에서 언급한 것처럼 PyCharm의 최신 버전을 사용하고 있지 않은 것 같습니다. 2016.3.2 버전으로 전환해보세요. 불행히도, 이는 잘 알려진 버그입니다. @AshwiniChaudhary의 코멘트대로 말입니다.
More, the reported issue (for the last version of PyCharm) was submitted on December, last year. They probably fixed it and pushed the modifications into the same version.
또한, 최신 버전의 PyCharm에서 보고된 이슈는 작년 12월에 제출되었습니다. 그들은 이를 수정하고 같은 버전에 수정 사항을 푸시했을 가능성이 큽니다.
가장 최근 달린 Solution
This isn't a direct answer to the question, but I think it is a better solution.
이것은 직접적인 대답은 아니지만, 더 나은 해결책 같습니다.
I'm using the typing specification below, using Iterator[int]
instead of Generator. The validation is OK. I think it is a lot clearer. It better describes the code intention and is recommended by Python docs.
제가 사용하는 typing 명세는 Iterator[int]이고 Generator 대신 사용합니다. 검증이 잘 됩니다. 코드의 의도를 더 잘 설명하고 Python 문서에서 권장하는 방법입니다.
from typing import Iterator
def generate() -> Iterator[int]:
for i in range(10):
yield i
It would also allow future refactorings if you change your Generator for a list or other iterable.
Generator를 리스트나 기타 iterable로 바꾸는 경우에도 미래 리팩토링을 허용합니다.
I'm using Visual Studio Code with PyLance for typing validation. PyCharm mypy should have the same behavior.
저는 PyLance를 사용하는 Visual Studio Code를 사용합니다. PyCharm mypy도 동일한 동작을 합니다.
If you are using Python 3.10 or superior, change the import command above to:
Python 3.10 이상을 사용하는 경우, 위의 import 명령을 다음과 같이 변경하세요:
from collections.abc import Iterator
출처 : https://stackoverflow.com/questions/42531143/how-to-type-hint-a-generator-in-python-3