Type hints w języku Python Konrad Hałas 4Developers 2018
Plan type hints dlaczego? składnia narzędzia biblioteki projekty legacy
def notify_everyone (items): for item in items: item.owner.notify()
def cancel_all (items): notify_everyone(items) ...
Rozwiązania dokumentacja zewnętrzna dokumentacja w kodzie (RST, epytext, NumPy, Google) przepisać wszystko do języka statycznie typowanego
def count_unique_words (text, case_sensitive): ...
def count_unique_words (text: str, case_sensitive: bool) ‑> int: ...
def median (values: list) ‑> float: ...
from typing import List def median (values: List[float]) ‑> float: ...
from typing import Dict def count_chars (text: str) ‑> Dict[str, int]: ...
from typing import List class Point : ... def calculate_area (vertices: List[Point]) ‑> float: ...
from typing import Optional def total_amount (order: Order, discount: Optional[Discount]) ‑> Money: ...
from typing import List, Union def send_confirmation (email: Union[str, List[str]]) ‑> None : ...
from typing import Any def get_most_frequent (items: list) ‑> Any: ...
from typing import List, TypeVar T = TypeVar('T') def get_most_frequent (items: List[T]) ‑> T: ...
from typing import List class Item : ... class Basket : def __init__ (self): self.items: List[Item] = [] def add_item (self, item: Item): self.items.append(item)
Narzędzia mypy PyCharm ...
def total_price (items: List[Item], discount: Optional[float] = None) ‑> float: ...
def total_price (items: List[Item], discount: Optional[float] = None) ‑> float: result = 0.0 for item in items: result += item.count * item.product.price result ‑= discount return result
def total_price (items: List[Item], discount: Optional[float] = None) ‑> float: result = 0.0 for item in items: result += item.count * item.product.price result ‑= discount return result $ mypy ‑‑strict example.py example.py:9: error: "Item" has no attribute "count" example.py:10: error: Unsupported operand types for ‑ ("float" and "Optional[float]")
def total_price (items: List[Item], discount: Optional[float] = None) ‑> float: result = 0.0 for item in items: result += item.quantity * item.product.price if discount: result ‑= discount return result $ mypy ‑‑strict example.py
Biblioteki injector dacite ...
def register_user (user_details: UserDetails): ...
from users.repositories import UsersRepository def register_user (user_details: UserDetails): ... repository = UsersRepository() repository.create_user(...)
class UsersService : def __init__ (self, repository: UsersRepository): self.repository = repository def register_user (self, user_details: UserDetails): ... self.repository.create_user(...)
class UsersRepository : def __init__ (self, data_base: DataBase): self.data_base = data_base def create_user (self, user: User): ... self.data_base.insert(...)
class DataBase : def __init__ (self, session: DataBaseSession): self.session = session ...
session = DataBaseSession(...) data_base = DataBase(session) users_repository = UsersRepository(data_base) users_service = UsersService(users_repository)
class DataBaseSession : ... class DataBase : def __init__ (self, session: DataBaseSession): ... class UsersRepository : def __init__ (self, database: DataBase): ... class UsersService : def __init__ (self, repository: UsersRepository): ...
from injector import inject class DataBaseSession : ... class DataBase : @inject def __init__ (self, session: DataBaseSession): ... class UsersRepository : @inject def __init__ (self, database: DataBase): ... class UsersService : @inject def __init__ (self, repository: UsersRepository): ...
from injector import Injector users_service = Injector().get(UsersService)
from dataclasses import dataclass @dataclass class User : name: str age: int is_active: bool user = User(name='John', age=30, is_active= True )
import dacite data = { 'name': 'John', 'age': 30, 'is_active': True , } user = dacite.from_dict(data_class=User, data=data) assert user == User(name='John', age=30, is_active= True )
Type hints w projekcie legacy gradual typing statyczna analiza uruchamiana w ramach CI wymuszanie type annotations dla: kluczowych modułów interfejsów
Podsumowanie zrozumiały kod mniej błędów nowe możliwości
Dziękuję! @konradhalas / konradhalas.pl
Zdjęcia Jacek Kołodziej ‑ http://kolodziejj.info/ Korsan Studio ‑ http://facebook.com/korsanstudio
Narzędzia/biblioteki mypy ‑ http://mypy‑lang.org PyCharm ‑ https://www.jetbrains.com/pycharm dacite ‑ https://github.com/konradhalas/dacite injector ‑ https://github.com/alecthomas/injector
Recommend
More recommend