Successfully reported this slideshow.

Types my way: Static Typing in Python

0

Share

Loading in …3
×
1 of 27
1 of 27

Types my way: Static Typing in Python

0

Share

Download to read offline

Description

Static typing in Python

Transcript

  1. 1. Types my way: Static typing in Python Joe Cabrera
  2. 2. Dynamically typing The Python interpreter checks types as your code runs and the type of variable can change during it’s lifetime >>> thing = "hello" >>> type(thing) <class 'str'> >>> thing = 29.0 >>> type(thing) <class 'float'>
  3. 3. Static Typing Static typing checks run without even running the program, usually when the code is compiled (C++ and Java) String thing; thing = "Hello";
  4. 4. Duck Typing “If it walks like a duck and it quacks like a duck, this it must be a duck” You do not check types at all, instead you check if an object has a method or attribute >>> class Malort: ... def __str__(self): ... return "Jeppson's Malört" ... def __format__(self, format): ... if(format == 'where'): ... return "only in chicago" ... return "None" ... >>> print(format(Malort(), "where")) only in chicago
  5. 5. def get_caching_header(args=None): """ Get cache header dictionary. :param args: Query arguments for used to build surrogate key :type args: dict :return: Cache header dictionary """
  6. 6. def get_caching_header(args=None): """ Get cache header dictionary. """ assert type(args) is dict
  7. 7. Optional Type Checking - Compile-time type checking - Easier to find bugs - Less debugging - Easier maintenance - Machine-checked documentation - Easier to understand code - Grow from dynamic to static typing - You can add static typing existing codebases after your code has matured - You can gradually add type hints with Any
  8. 8. Why should you start type checking now? ● Great for complex and confusing code ● Good for open-source code ● Before migrating or refactoring code
  9. 9. PEP 484: Type Hints Python will remain a dynamically typed language, and the authors have no desire to ever make type hints mandatory, even by convention. Type hints have no runtime effect >>> def shot(location: str) -> str: ... if location == "new york": ... return "hennessy" ... elif location == "chicago": ... return "evan williams" ... else: ... return "jack daniels"
  10. 10. Function annotations Functions can have annotation arguments and return value >>> def beer(location: str, with_shot: bool = True) -> str: ... >>> beer.__annotations__ {'location': <class 'str'>, 'with_shot': <class 'bool'>}
  11. 11. Variable annotations Available since Python 3.6 >>> speed_of_sound: float = 343.0
  12. 12. Type & Variable Comments Annotations are great, but have not been backported to Python 2.x Type comments can be used in any version of Python >>> def beer(location, with_shot): >>> # type: (str, bool) -> str >>> ... >>> speed_of_sound = 343.0 # type: float
  13. 13. Sequences & Mappings Great we can do primitives but what about composite types. Also not an issue… >>> beers: list = ["Coors Light", "Budweiser", "Corona"] >>> shots: tuple = ("B-52", "Irish Car Bomb", "Lemon Drop") >>> beer_shot: dict = {"Coors Light": "Jack Daniels", "Corona": "Tequila"}
  14. 14. Typing module Composite types are great, but what about the individual values >>> from typing import Dict, List, Tuple >>> beers: List[str] = ["Coors Light", "Budweiser", "Corona"] >>> shots: Tuple[str, str, str] = ("B-52", "Irish Car Bomb", "Lemon Drop") >>> beer_shot: Dict[str, str] = {"Coors Light": "Jack Daniels", >>> ... "Corona": "Tequila"}
  15. 15. Sequences Many times you expect some kind of sequence but do not care if it’s a list or a tuple >>> from typing import List, Sequence >>> >>> def take_shot(liquors: Sequence[str]) -> str: >>> return random.choice(liquors)
  16. 16. Type Aliases Instead of Write this >>> from typing import List, Tuple >>> >>> def take_shots(beer_shot: List[Tuple[str, str]]) -> Tuple[ >>> List[Tuple[str, str]], >>> List[Tuple[str, str]], >>> List[Tuple[str, str]], >>> ]: >>> return (beer_shot[0::3], beer_shot[1::3], beer_shot[2::3]) >>> from typing import List, Tuple >>> Boilermaker = Tuple[str, str]
  17. 17. Functions without return values >>> def shot(location: str) -> None: ... if location == "new york": ... print("hennessy") ... elif location == "chicago": ... print("evan williams") ... else: ... print("jack daniels") >>> from typing import NoReturn >>> >>> def the_darkness() -> NoReturn: raise Exception("It's too late")
  18. 18. The magically Any type >>> from typing import Any, Sequence >>> >>> def take_shot(liquors: Sequence[Any]) -> Any: >>> return random.choice(liquors)
  19. 19. The Optional Type For functions that have a default value for an argument >>> from typing import Sequence, Optional >>> >>> def beer_order(names: Sequence[str], >>> ... start: Optional[str] = None) -> Sequence[str]:
  20. 20. The Union Type When you need arguments of several types in a composite >>> from typing import Union >>> >>> def beer_order(nashville_beer: Union[str, int]) -> Sequence[str]:
  21. 21. Annonating *args and **kwargs >>> class Bar >>> def __init__(self, beers: List[Beer], >>> *customer: str, >>> **drink_types: str) -> None: >>> self.beers = beers
  22. 22. Callables >>> from typing import Callable >>> >>> def take_shot(func: Callable[[str], str], argument: str) -> None: >>> print(func(argument)) >>> >>> def create_response(liquor: str) -> str: >>> return f"A shot of {liquor}" >>> >>> take_shot(create_response, "Jack Daniels")
  23. 23. Protocols >>> class Bar: >>> def meth(self) -> int: >>> return 0 >>> >>> def func(x: Proto) -> int: >>> return x.meth()
  24. 24. Classes as Types >>> class Bar >>> def __init__(self, beers: List[Beer]) -> None: >>> self.beers = beers >>> >>> @classmethod >>> def open(cls, restock: bool = False) -> "Bar": return cls(beers)
  25. 25. Coming in Python 4.0 >>> from __future__ import annotations >>> >>> class Bar >>> >>> @classmethod >>> def open(cls, restock: bool = False) -> Bar: >>> return cls(beers)
  26. 26. Type-checkers Static ● MyPy (Dropbox) ● PyType (Google) ● Pyre (Facebook) ● Pyright (Microsoft) ● PyCharm Dynamic ● Enforce, Typeguard, Typo
  27. 27. Thanks! @greedoshotlast

Description

Static typing in Python

Transcript

  1. 1. Types my way: Static typing in Python Joe Cabrera
  2. 2. Dynamically typing The Python interpreter checks types as your code runs and the type of variable can change during it’s lifetime >>> thing = "hello" >>> type(thing) <class 'str'> >>> thing = 29.0 >>> type(thing) <class 'float'>
  3. 3. Static Typing Static typing checks run without even running the program, usually when the code is compiled (C++ and Java) String thing; thing = "Hello";
  4. 4. Duck Typing “If it walks like a duck and it quacks like a duck, this it must be a duck” You do not check types at all, instead you check if an object has a method or attribute >>> class Malort: ... def __str__(self): ... return "Jeppson's Malört" ... def __format__(self, format): ... if(format == 'where'): ... return "only in chicago" ... return "None" ... >>> print(format(Malort(), "where")) only in chicago
  5. 5. def get_caching_header(args=None): """ Get cache header dictionary. :param args: Query arguments for used to build surrogate key :type args: dict :return: Cache header dictionary """
  6. 6. def get_caching_header(args=None): """ Get cache header dictionary. """ assert type(args) is dict
  7. 7. Optional Type Checking - Compile-time type checking - Easier to find bugs - Less debugging - Easier maintenance - Machine-checked documentation - Easier to understand code - Grow from dynamic to static typing - You can add static typing existing codebases after your code has matured - You can gradually add type hints with Any
  8. 8. Why should you start type checking now? ● Great for complex and confusing code ● Good for open-source code ● Before migrating or refactoring code
  9. 9. PEP 484: Type Hints Python will remain a dynamically typed language, and the authors have no desire to ever make type hints mandatory, even by convention. Type hints have no runtime effect >>> def shot(location: str) -> str: ... if location == "new york": ... return "hennessy" ... elif location == "chicago": ... return "evan williams" ... else: ... return "jack daniels"
  10. 10. Function annotations Functions can have annotation arguments and return value >>> def beer(location: str, with_shot: bool = True) -> str: ... >>> beer.__annotations__ {'location': <class 'str'>, 'with_shot': <class 'bool'>}
  11. 11. Variable annotations Available since Python 3.6 >>> speed_of_sound: float = 343.0
  12. 12. Type & Variable Comments Annotations are great, but have not been backported to Python 2.x Type comments can be used in any version of Python >>> def beer(location, with_shot): >>> # type: (str, bool) -> str >>> ... >>> speed_of_sound = 343.0 # type: float
  13. 13. Sequences & Mappings Great we can do primitives but what about composite types. Also not an issue… >>> beers: list = ["Coors Light", "Budweiser", "Corona"] >>> shots: tuple = ("B-52", "Irish Car Bomb", "Lemon Drop") >>> beer_shot: dict = {"Coors Light": "Jack Daniels", "Corona": "Tequila"}
  14. 14. Typing module Composite types are great, but what about the individual values >>> from typing import Dict, List, Tuple >>> beers: List[str] = ["Coors Light", "Budweiser", "Corona"] >>> shots: Tuple[str, str, str] = ("B-52", "Irish Car Bomb", "Lemon Drop") >>> beer_shot: Dict[str, str] = {"Coors Light": "Jack Daniels", >>> ... "Corona": "Tequila"}
  15. 15. Sequences Many times you expect some kind of sequence but do not care if it’s a list or a tuple >>> from typing import List, Sequence >>> >>> def take_shot(liquors: Sequence[str]) -> str: >>> return random.choice(liquors)
  16. 16. Type Aliases Instead of Write this >>> from typing import List, Tuple >>> >>> def take_shots(beer_shot: List[Tuple[str, str]]) -> Tuple[ >>> List[Tuple[str, str]], >>> List[Tuple[str, str]], >>> List[Tuple[str, str]], >>> ]: >>> return (beer_shot[0::3], beer_shot[1::3], beer_shot[2::3]) >>> from typing import List, Tuple >>> Boilermaker = Tuple[str, str]
  17. 17. Functions without return values >>> def shot(location: str) -> None: ... if location == "new york": ... print("hennessy") ... elif location == "chicago": ... print("evan williams") ... else: ... print("jack daniels") >>> from typing import NoReturn >>> >>> def the_darkness() -> NoReturn: raise Exception("It's too late")
  18. 18. The magically Any type >>> from typing import Any, Sequence >>> >>> def take_shot(liquors: Sequence[Any]) -> Any: >>> return random.choice(liquors)
  19. 19. The Optional Type For functions that have a default value for an argument >>> from typing import Sequence, Optional >>> >>> def beer_order(names: Sequence[str], >>> ... start: Optional[str] = None) -> Sequence[str]:
  20. 20. The Union Type When you need arguments of several types in a composite >>> from typing import Union >>> >>> def beer_order(nashville_beer: Union[str, int]) -> Sequence[str]:
  21. 21. Annonating *args and **kwargs >>> class Bar >>> def __init__(self, beers: List[Beer], >>> *customer: str, >>> **drink_types: str) -> None: >>> self.beers = beers
  22. 22. Callables >>> from typing import Callable >>> >>> def take_shot(func: Callable[[str], str], argument: str) -> None: >>> print(func(argument)) >>> >>> def create_response(liquor: str) -> str: >>> return f"A shot of {liquor}" >>> >>> take_shot(create_response, "Jack Daniels")
  23. 23. Protocols >>> class Bar: >>> def meth(self) -> int: >>> return 0 >>> >>> def func(x: Proto) -> int: >>> return x.meth()
  24. 24. Classes as Types >>> class Bar >>> def __init__(self, beers: List[Beer]) -> None: >>> self.beers = beers >>> >>> @classmethod >>> def open(cls, restock: bool = False) -> "Bar": return cls(beers)
  25. 25. Coming in Python 4.0 >>> from __future__ import annotations >>> >>> class Bar >>> >>> @classmethod >>> def open(cls, restock: bool = False) -> Bar: >>> return cls(beers)
  26. 26. Type-checkers Static ● MyPy (Dropbox) ● PyType (Google) ● Pyre (Facebook) ● Pyright (Microsoft) ● PyCharm Dynamic ● Enforce, Typeguard, Typo
  27. 27. Thanks! @greedoshotlast

More Related Content

Related Books

Free with a 30 day trial from Scribd

See all

×