Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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"

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

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

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

    Annotations • 2014-09-29 • Python 3.5
  5. def add(a: int, b: int) -> int: return a +

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

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

  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]
  9. def get_list(a: int, b: int) -> List: return ['a', a,

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

    'b', b, 'a + b', a + b]
  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]
  12. def func(text: str) -> str: result: int = some_complex_func(text) return

    str(result)
  13. class Person: def __init__(self, name: str) -> None: self.name: str

    = name self.length_of_name: int = len(name)
  14. from typing import List, Union result: List[Union[int, str]] = [1,

    'a', 2, 'b']
  15. from typing import Optional, Union assert Optional[int] == Union[int, None]

  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}
  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
  18. from typing import Tuple def get_tuple(a: int, b: int) ->

    Tuple[int, int]: return a, b
  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
  20. from typing import Tuple def get_tuple() -> Tuple[int, ...]: return

    1, 2, 3, 4, 5, 6, 7, 8, 9, 10
  21. from typing import Callable def add_lazy(a: int, b: int): def

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

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

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

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

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

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

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

    int: return f(kwargs)
  29. IntReturningFunction = Callable[..., int] def run(f: IntReturningFunction) -> int: return

    f(1, 2, 3, 4, 5)
  30. def fetch(_id: int, category: int) -> Transaction: pass

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

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

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

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

    List['Person']: pass
  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)
  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)
  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)
  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)
  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)
  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)
  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."""
  42. # some other package (math.py) def add(a, b): return a

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

  44. None
  45. python/typeshed • contains external type annotations for the Python standard

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

    library and Python builtins • as well as third party packages.
  47. None
  48. None
  49. None
  50. None
  51. None
  52. None
  53. [mypy] disallow_untyped_defs = True strict_optional = True warn_redundant_casts = True

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

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

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

    ఋੑ ୶ۿ ѐࢶ • ੿੸ Type Checkerܳ ాೠ पࣻ ߑ૑
  57. :-1: • ҃਋ী ٮۄ ࠛ೙ਃೠ ௏٘੄ ୶о

  58. :-1: • ҃਋ী ٮۄ ࠛ೙ਃೠ ௏٘੄ ୶о • (ই૒਷) ׮ࣗ

    ࠗ઒ೠ ఋੑ दझమ
  59. “Python is dynamically typed and we like it that way!”

    - Guido van Rossum
  60. ۨ੉פझ౟ীࢲח • ఋੑ ݺदо ௏٘੄ оةࢿਸ ֫ੋ׮Ҋ ޺ਵݴ ೐۽ં౟ ҙܻ

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

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

    ࠺ਊਸ ծ୹ ࣻ ੓׮Ҋ ౸ױೞৈ بੑ೮णפ׮. • नӏ ೐۽ં౟ח CI җ੿ীࢲ mypyܳ प೯೤פ׮. • ఋੑ दझమ੄ ೠ҅۽ ੋ೧ ࠛ೙ਃೠ ௏٘ܳ ੘ࢿ೧ঠ ೡ ٸ ীח @typing.no_type_check
  63. ߛ௼࢟۞٘ܳ ݅٘ח ۨ੉פझ౟ীࢲ ੷൞ ৬ ೣԋೡ ࢲߡ ূ૑פয ٜ࠙ਸ ଺Ҋ

    ੓ णפ׮. Python, aiohttp, django
  64. Questions github: sunghyunzz email: [email protected]