$30 off During Our Annual Pro Sale. View Details »

Python Type Hints

Python Type Hints

제 3회 파이썬 격월 세미나에서 발표한 [Python Type Hints] 발표 슬라이드입니다. (https://www.facebook.com/groups/pythonkorea/)

Sunghyun Hwang

March 25, 2017
Tweet

More Decks by Sunghyun Hwang

Other Decks in Programming

Transcript

  1. Python Type Hints
    presenter: str = "sunghyunzz"

    View Slide

  2. PEP 484 - Type Hints
    • PEP 3107 - Function Annotations

    View Slide

  3. PEP 484 - Type Hints
    • PEP 3107 - Function Annotations
    • 2014-09-29

    View Slide

  4. PEP 484 - Type Hints
    • PEP 3107 - Function Annotations
    • 2014-09-29
    • Python 3.5

    View Slide

  5. def add(a: int, b: int) -> int:
    return a + b

    View Slide

  6. def print_sum(a: int, b: int) -> None:
    print(a + b)

    View Slide

  7. def get_list(a: int, b: int) -> list:
    return [a, b]

    View Slide

  8. def get_list(a: int, b: int) -> list:
    return [a, b]
    from typing import List
    def get_list(a: int, b: int) -> List[int]:
    return [a, b]

    View Slide

  9. def get_list(a: int, b: int) -> List:
    return ['a', a, 'b', b, 'a + b', a + b]

    View Slide

  10. def get_list(a: int, b: int) -> List:
    return ['a', a, 'b', b, 'a + b', a + b]

    View Slide

  11. def get_list(a: int, b: int) -> list:
    return [a, b]
    from typing import Any, List
    def get_list(a: int, b: int) -> List[Any]:
    return ['a', a, 'b', b, 'a + b', a + b]

    View Slide

  12. def func(text: str) -> str:
    result: int = some_complex_func(text)
    return str(result)

    View Slide

  13. class Person:
    def __init__(self, name: str) -> None:
    self.name: str = name
    self.length_of_name: int = len(name)

    View Slide

  14. from typing import List, Union
    result: List[Union[int, str]] = [1, 'a', 2, 'b']

    View Slide

  15. from typing import Optional, Union
    assert Optional[int] == Union[int, None]

    View Slide

  16. from typing import Dict, Set
    def get_dict(a: int) -> Dict[int, str]:
    return {
    a: str(a),
    a + 1: str(a + 1)
    }
    def get_set(a: int) -> Set[int]:
    return {a, a + 1}

    View Slide

  17. from typing import Tuple
    def get_tuple(a: int, b: int) -> Tuple[int]:
    return a, b # Expected type 'Tuple[int]', got 'Tuple[int, int]' instead

    View Slide

  18. from typing import Tuple
    def get_tuple(a: int, b: int) -> Tuple[int, int]:
    return a, b

    View Slide

  19. from typing import Tuple
    def get_tuple() -> Tuple[int, int, int, int, int, int, int, int, int, int]:
    return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

    View Slide

  20. from typing import Tuple
    def get_tuple() -> Tuple[int, ...]:
    return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

    View Slide

  21. from typing import Callable
    def add_lazy(a: int, b: int):
    def f() -> int:
    return a + b
    return f

    View Slide

  22. from typing import Callable
    def add_lazy(a: int, b: int) -> Callable[[], int]:
    def f() -> int:
    return a + b
    return f

    View Slide

  23. from typing import Callable
    def run(f: Callable[[int, str], int], a: int, b: str) -> int:
    return f(a, b)

    View Slide

  24. def run(f: Callable[..., int], *args) -> int:
    return f(args)

    View Slide

  25. def run(f: Callable[..., int], *args: int) -> int:
    return f(args)

    View Slide

  26. def run(
    f: Callable[[Dict[str, int]], int],
    **kwargs: int
    ) -> int:
    return f(kwargs)

    View Slide

  27. def run(
    f: Callable[[Dict[str, int]], int],
    **kwargs: int
    ) -> int:
    return f(kwargs)

    View Slide

  28. def run(
    f: Callable[[Dict[str, int]], int],
    **kwargs: int
    ) -> int:
    return f(kwargs)

    View Slide

  29. IntReturningFunction = Callable[..., int]
    def run(f: IntReturningFunction) -> int:
    return f(1, 2, 3, 4, 5)

    View Slide

  30. def fetch(_id: int, category: int) -> Transaction:
    pass

    View Slide

  31. EntityID = int
    def fetch(_id: EntityID, category: int) -> Transaction:
    pass

    View Slide

  32. class Person:
    def get_children(self) -> List[Person]:
    pass

    View Slide

  33. class Person:
    def get_children(self) -> List[Person]:
    pass
    NameError: name 'Person' is not defined

    View Slide

  34. class Person:
    def get_children(self) -> List[Person]:
    pass
    def get_children(self) -> List['Person']:
    pass

    View Slide

  35. from abc import ABCMeta, abstractmethod
    from typing import Generic, TypeVar
    T = TypeVar('T')
    class Person:
    pass
    class Mapper(Generic[T], metaclass=ABCMeta):
    @classmethod
    @abstractmethod
    def from_dict(cls, request: dict) -> T:
    pass
    def convert(mapper: Mapper[Person], data: dict) -> Person:
    return mapper.from_dict(data)

    View Slide

  36. from abc import ABCMeta, abstractmethod
    from typing import Generic, TypeVar
    T = TypeVar('T')
    class Person:
    pass
    class Mapper(Generic[T], metaclass=ABCMeta):
    @classmethod
    @abstractmethod
    def from_dict(cls, request: dict) -> T:
    pass
    def convert(mapper: Mapper[Person], data: dict) -> Person:
    return mapper.from_dict(data)

    View Slide

  37. from abc import ABCMeta, abstractmethod
    from typing import Generic, TypeVar
    T = TypeVar('T')
    class Person:
    pass
    class Mapper(Generic[T], metaclass=ABCMeta):
    @classmethod
    @abstractmethod
    def from_dict(cls, request: dict) -> T:
    pass
    def convert(mapper: Mapper[Person], data: dict) -> Person:
    return mapper.from_dict(data)

    View Slide

  38. from abc import ABCMeta, abstractmethod
    from typing import Generic, TypeVar
    T = TypeVar('T')
    class Person:
    pass
    class Mapper(Generic[T], metaclass=ABCMeta):
    @classmethod
    @abstractmethod
    def from_dict(cls, request: dict) -> T:
    pass
    def convert(mapper: Mapper[Person], data: dict) -> Person:
    return mapper.from_dict(data)

    View Slide

  39. from abc import ABCMeta, abstractmethod
    from typing import Generic, TypeVar
    T = TypeVar('T')
    class Person:
    pass
    class Mapper(Generic[T], metaclass=ABCMeta):
    @classmethod
    @abstractmethod
    def from_dict(cls, request: dict) -> T:
    pass
    def convert(mapper: Mapper[Person], data: dict) -> Person:
    return mapper.from_dict(data)

    View Slide

  40. from abc import ABCMeta, abstractmethod
    from typing import Generic, TypeVar
    T = TypeVar('T')
    class Person:
    pass
    class Mapper(Generic[T], metaclass=ABCMeta):
    @classmethod
    @abstractmethod
    def from_dict(cls, request: dict) -> T:
    pass
    def convert(mapper: Mapper[Person], data: dict) -> Person:
    return mapper.from_dict(data)

    View Slide

  41. python2 support
    from typing import List
    def hello(): # type: () -> None
    print 'hello'
    class Example:
    def method(self, lst, opt=0, *args, **kwargs):
    # type: (List[str], int, *str, **bool) -> int
    """Docstring comes after type comment."""

    View Slide

  42. # some other package (math.py)
    def add(a, b):
    return a + b

    View Slide

  43. # stub (math.pyi)
    def add(a: float, b: float) -> float: …

    View Slide

  44. View Slide

  45. python/typeshed
    • contains external type annotations for the
    Python standard library and Python builtins

    View Slide

  46. python/typeshed
    • contains external type annotations for the
    Python standard library and Python builtins
    • as well as third party packages.

    View Slide

  47. View Slide

  48. View Slide

  49. View Slide

  50. View Slide

  51. View Slide

  52. View Slide

  53. [mypy]
    disallow_untyped_defs = True
    strict_optional = True
    warn_redundant_casts = True

    View Slide

  54. :+1:
    • ޙࢲച੄ ӝמ (ӝઓ੄ docstring convention ؀୓)

    View Slide

  55. :+1:
    • ޙࢲച੄ ӝמ (ӝઓ੄ docstring convention ؀୓)
    • IDE/ী٣ఠ ఋੑ ୶ۿ ѐࢶ

    View Slide

  56. :+1:
    • ޙࢲച੄ ӝמ (ӝઓ੄ docstring convention ؀୓)
    • IDE/ী٣ఠ ఋੑ ୶ۿ ѐࢶ
    • ੿੸ Type Checkerܳ ాೠ पࣻ ߑ૑

    View Slide

  57. :-1:
    • ҃਋ী ٮۄ ࠛ೙ਃೠ ௏٘੄ ୶о

    View Slide

  58. :-1:
    • ҃਋ী ٮۄ ࠛ೙ਃೠ ௏٘੄ ୶о
    • (ই૒਷) ׮ࣗ ࠗ઒ೠ ఋੑ दझమ

    View Slide

  59. “Python is dynamically typed and
    we like it that way!”
    - Guido van Rossum

    View Slide

  60. ۨ੉פझ౟ীࢲח
    • ఋੑ ݺदо ௏٘੄ оةࢿਸ ֫ੋ׮Ҋ ޺ਵݴ ೐۽ં౟ ҙܻ
    ࠺ਊਸ ծ୹ ࣻ ੓׮Ҋ ౸ױೞৈ بੑ೮णפ׮.

    View Slide

  61. ۨ੉פझ౟ীࢲח
    • ఋੑ ݺदо ௏٘੄ оةࢿਸ ֫ੋ׮Ҋ ޺ਵݴ ೐۽ં౟ ҙܻ
    ࠺ਊਸ ծ୹ ࣻ ੓׮Ҋ ౸ױೞৈ بੑ೮णפ׮.
    • नӏ ೐۽ં౟ח CI җ੿ীࢲ mypyܳ प೯೤פ׮.

    View Slide

  62. ۨ੉פझ౟ীࢲח
    • ఋੑ ݺदо ௏٘੄ оةࢿਸ ֫ੋ׮Ҋ ޺ਵݴ ೐۽ં౟ ҙܻ
    ࠺ਊਸ ծ୹ ࣻ ੓׮Ҋ ౸ױೞৈ بੑ೮णפ׮.
    • नӏ ೐۽ં౟ח CI җ੿ীࢲ mypyܳ प೯೤פ׮.
    • ఋੑ दझమ੄ ೠ҅۽ ੋ೧ ࠛ೙ਃೠ ௏٘ܳ ੘ࢿ೧ঠ ೡ ٸ
    ীח @typing.no_type_check

    View Slide

  63. ߛ௼࢟۞٘ܳ ݅٘ח ۨ੉פझ౟ীࢲ ੷൞
    ৬ ೣԋೡ ࢲߡ ূ૑פয ٜ࠙ਸ ଺Ҋ ੓
    णפ׮.
    Python, aiohttp, django

    View Slide

  64. Questions
    github: sunghyunzz
    email: [email protected]

    View Slide