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

Контрактное программирование и классы данных в Python

Контрактное программирование и классы данных в Python

Сергей Левитин (Python & Go разработчик в Ostrovok.ru) @ Moscow Python Meetup № 41

"О том, как мы в Островке поддерживаем стабильность и расширяемость кода на Python вместе с PyContracts и типизированными Data-классами".

Видео: http://www.moscowpython.ru/meetup/41/kontraktnoe-programmirovanie-i-klassy-dannyh-v-pyt/

Moscow Python Meetup

December 22, 2016
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. Что такое контракты? - Контракты – это правила валидации входных

    и выходных параметров функций; - Для работы с контрактами в Python мы используем библиотеку PyContracts.
  2. Пример функции с контрактом from contracts import contract @contract def

    sum(a, b): """ :type a: int|float > 0 :type b: int|float > 0 :rtype: int|float """ Функция sum принимает два аргумента типа int или float и возвращает значение соответствующего типа.
  3. Для чего нужны контракты? - Чтобы сделать динамически типизированный код

    стабильнее и защищеннее; - Чтобы писать больше тестов для бизнес-логики и не заморачиваться с проверкой корректности структур данных.
  4. Классы данных - Класс данных — это класс, который хранит

    только данные без описания поведения; - Мы используем собственное решение TypedDict для создания Data-классов.
  5. Пример класса данных class BookingResult(TypedDict): user_id = f.PositiveInt() order_id =

    f.PositiveInt() created_at = f.DateTime() comment = opt(f.StringNotEmpty) Класс BookingResult хранит информацию о результате бронирования.
  6. Для чего нужны классы данных? - Они помогают упростить обмен

    данными между сервисами; - Когда разработчик создает API, он описывает формат входных и выходных данных в классе и прикрепляет ссылку на этот класс к описанию API; - Поддержка валидации полей помогает не писать утомительные проверки для входных данных.
  7. Контракты вместе с Data-классами class BookingRequest(TypedDict): ROOM_TYPES = ('Economy', 'Standard',

    'Premium') hotel_id = f.PositiveInt() checkin_date = f.Date() checkout_date = f.Date() room_type = f.StringNotEmpty(choices=ROOM_TYPES) Определим класс BookingRequest, который описывает структуру запроса для создания брони.
  8. class BookingResult(TypedDict): user_id = f.PositiveInt() order_id = f.PositiveaInt() created_at =

    f.DateTime() price = f.Decimal() comment = opt(f.StringNotEmpty) В классе BookingResult будет храниться информация о результате бронирования.
  9. @contract def make_booking(request: BookingRequest) -> BookingResult: # ... return BookingResult(

    user_id=1, order_id=10, created_at=datetime.now(), price=Decimal('10000'), comment='hello!' ) Функция make_booking принимает BookingRequest, выполняет бронирование и возвращает BookingResult.
  10. Классы данных в тестах book_request = BookingRequest( hotel_id=10, checkin_date=datetime.date(2016, 01,

    02) checkout_date=datetime.date(2016, 01, 10), ) response = self.post('/api/book/', data=book_request.simplify()) self.assertEqual(response.status, 200) # validate correct response format book_result = BookingResult(**response.json()) self.assertEqual(book_result.order_id, 10)
  11. Удобство написания и поддержки тестов - Классы данных помогают избавиться

    от ручных проверок структур данных в тестах и сосредоточиться на тестировании бизнес-логики. - Контракты дают уверенность в корректности типов аргументов и возвращаемых значений; - Увеличивается качество регрессивного тестирования засчет двух предыдущих пунктов.
  12. Приятные мелочи - Pycontracts поддерживает синтаксис Python 3 type hinting;

    - Контракты проверяются только в тестовом окружении и не замедляют продуктив; - TypedDict поддерживает простую сериализацию и десериализацию данных в JSON/XML/Msgpack.
  13. Резюмируя - Ваш продукт начинает работать стабильнее; - Код становится

    более поддерживаемым и тестируемым; - А разработчики и QA — немного счастливее. C контрактами и классами данных
  14. Полезные ссылки - PyContracts: https://andreacensi.github.io/contracts/ - Библиотеки TypedDict пока нет

    в Open Source. Вместо него можно использовать Schematics: https://schematics.readthedocs.io/en/latest/