Typing.Dict와 dict의 차이점은 무엇입니까?


106

저는 Python 3.5에서 유형 힌트를 사용하여 연습하고 있습니다. 내 동료 중 한 명이 다음을 사용합니다 typing.Dict.

import typing


def change_bandwidths(new_bandwidths: typing.Dict,
                      user_id: int,
                      user_name: str) -> bool:
    print(new_bandwidths, user_id, user_name)
    return False


def my_change_bandwidths(new_bandwidths: dict,
                         user_id: int,
                         user_name: str) ->bool:
    print(new_bandwidths, user_id, user_name)
    return True


def main():
    my_id, my_name = 23, "Tiras"
    simple_dict = {"Hello": "Moon"}
    change_bandwidths(simple_dict, my_id, my_name)
    new_dict = {"new": "energy source"}
    my_change_bandwidths(new_dict, my_id, my_name)

if __name__ == "__main__":
    main()

둘 다 잘 작동하며 차이가없는 것 같습니다.

typing모듈 문서를 읽었습니다 .

사이 typing.Dict또는 dict어느 나는이 프로그램에 사용해야합니까?


11
Python은 실제로 유형 힌트를 적용 하지 않습니다 . 그것들은 단지 힌트뿐이며 , 유형을 적용하기 위해 런타임이나 컴파일 타임에 사용되지 않습니다. Python은 강력한 유형 (약한 유형의 반대) 일 수 있으며 동적 유형 (엄격한 유형의 반대)도 있습니다. Python은 강력한 형식입니까?를 참조하십시오 . . mypy와 같은 외부 도구는 이러한 힌트를 사용하여 정적 분석이라는 프로세스에서 더 나은 코드를 작성하는 데 도움을 줄 수 있습니다.
Martijn Pieters

1
@MartijnPieters MyPy와 함께 코드에서 유형 힌트를 사용하는 것을 좋아하고 Python을 유형 안전으로 사용할 수있는 척했습니다. 불행히도 A) 3.4 미만에서는 작동하지 않는 코드와 B) 분명히 유형 힌트가 웃음 거리이기 때문에 나를 비웃는 사람들이 있습니다. 정말 유감입니다.
cat

3
@cat : PHP에 동일한 기능을 추가하는 데 엄청난 성공을 거두었 기 때문에 유형 힌트는 Facebook 직원이 Python에 도입했습니다 ( hack 참조 ). 웃는 사람은 소수의 엔지니어로 큰 프로젝트를 만든 적이 없습니다.
Martijn Pieters

3
@MartijnPieters 아니요, def a(b: int) -> bool:Python 2.7의 구문 오류이며 이전 버전의 Python 3에서도 구문 오류라고 생각합니다.
cat

1
@cat : 여기서는 Python 3.0에 추가 된 구문 인 함수 주석 에 대해 이야기하고 있습니다 . 따라서 구문 오류 인 유일한 버전은 2.7이므로 mypy가 해당 정보를 주석에 넣는 것을 지원합니다.
Martijn Pieters

답변:


148

일반 사용 typing.Dictdict, 아니오 사용에는 실제 차이가 없습니다.

그러나 typing.DictA는 일반 유형 * 당신은 키와 값의 유형을 지정할 수 좀 더 유연하게는 :

def change_bandwidths(new_bandwidths: typing.Dict[str, str],
                      user_id: int,
                      user_name: str) -> bool:

따라서, 그것은 당신의 프로젝트 일생에 어떤 시점에서 당신이 확대되는 시점에서, 좀 더 정확하게 사전 인수를 정의하도록 수 typing.Dicttyping.Dict[key_type, value_type]교체보다 '작은'변화이다 dict.

여기에 Mapping또는 MutableMapping유형 을 사용하여 더 일반적으로 만들 수 있습니다 . 함수가 매핑 을 변경할 필요가 없기 때문에 Mapping. A dict는 하나의 매핑이지만 매핑 인터페이스를 만족하는 다른 개체를 만들 수 있으며 함수는 다음과 같이 잘 작동 할 수 있습니다.

def change_bandwidths(new_bandwidths: typing.Mapping[str, str],
                      user_id: int,
                      user_name: str) -> bool:

지금 당신은 명확하게 코드가 실제로되지 않습니다이 기능의 다른 사용자 말하고있다 변경new_bandwidths 전달 매핑.

실제 구현은 단순히 인쇄 가능한 객체를 기대합니다. 그것은 테스트 구현 일 수 있지만 new_bandwidths: typing.AnyPython의 모든 객체가 인쇄 가능하기 때문에을 사용하면 코드가 계속 작동합니다 .


* : 참고 : Python 3.7 이상을 사용 dict하는 경우으로 모듈을 시작하면 일반 유형으로 사용할 수 있으며 from __future__ import annotations, Python 3.9부터 dict(기타 표준 컨테이너 포함) 는 그렇지 않아도 일반 유형으로 사용되는 것을 지원합니다. 지시문 .


2
유용한 추가 예는 사전 값이 다른 유형일 수있는 경우입니다. 예를 들어 {"name": "bob", "age" : 51}, 다음과 같을 typing.Mapping[Union[str, int]까요? 중첩 된 사전 {"person": {"name":"bob", "age": 51}typing.Mapping[str, typing.Mapping[Union[str, int]]어떨까요? Union그렇게 사용하면 순서가 없기 때문에 엄격한 스키마가 아니기 때문에 문제가됩니다. 괜찮을 수도 있고 대안이 있습니까?
Davos

1
Union질문 에 대해 신경 쓰지 마세요.
Davos

1
이것은 매우 흥미롭고 유용하며 관련된 것 같습니다. python.org/dev/peps/pep-0589
Greg

@GregHilston : 실제로 사전에 포함 할 수있는 키를 제한하고 각 관련 값이 가져야하는 유형을 지정하는 방법에 대한 것입니다.
Martijn Pieters

1
@GregHilston : 아, 네, 그렇습니다.
Martijn Pieters

26

typing.Dict의 일반 버전입니다 dict.

class typing.Dict(dict, MutableMapping[KT, VT])

dict의 일반 버전입니다. 이 유형의 사용법은 다음과 같습니다.

def get_position_in_index(word_list: Dict[str, int], word: str) -> int:
     return word_list[word]

여기에서 dict의 키 및 값 유형을 지정할 수 있습니다. Dict[str, int]

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.