Рубрики
Без рубрики

Написать Unbreakable Python

В этой статье я покажу вам, как писать Python без исключений во время выполнения. Это будет заставить вас полунажатие писать код, который не нарушает и в основном делает то, что он должен делать. Мы сделаем это, узнав, как применить функциональное программирование в Python. с, может быть, либо, функциональным, питон меткий.

В этой статье я покажу вам, как писать Python без исключений во время выполнения. Это будет заставить вас полунажатие писать код, который не нарушает и в основном делает то, что он должен делать. Мы сделаем это, узнав, как применить функциональное программирование в Python. Мы рассмотрим:

  • обеспечить функции всегда работают путем обучения Pure функции
  • Ошибки избежать выполнения путем возврата Maybes
  • Ошибки во время выполнения избежать глубоко вложенных данных с помощью линзы
  • Ошибки избежать выполнения путем возврата результатов
  • создание чистых программ из чистых функций путем программирования трубопровода

Почему уход?

Написание кода, который не нарушает это так же, как обеспечить ваши зубы остаются здоровыми. Оба оказались способы предотвратить проблемы, но люди до сих пор действуют безответственно, либо при употреблении в пищу плохих продуктов, а не кистью, или в программировании заманивают на «Getting Things быстро работают с тем, что они знают».

Например, чтобы предотвратить кариес в зубах, следует избегать высокие пищевого сахара, пить общественное водоснабжение с фтором, и чистить зубы два раза в день. По крайней мере, в США, многие до сих пор проблемы с зубами . Проблема доступа для гигиены полости рта может быть экономической. Для других, они просто не отвечают и не держать на здоровье зубов.

Для программирования я могу помочь с проблемой доступа. Эта статья предоставит проверенные способы оснастить вас знаниями, которые помогут себе.

Однако для ответственности я сочувствую это сложнее. Я научу тебя технике, но Вы должны практиковать их. Чистка зубов каждый день, вы можете освоить его довольно быстро. Использование функциональных методов программирования в нефункциональном языке программирования требует намного больше практики и тяжелой работы.

Ваши зубы благодарим вас за чистку. Ваш код будет благодарен вам последовательно работает.

Что именно «никогда не ломается» имеется именно?

«Никогда не ломайся» означает, что функция всегда будет работать, всегда будет возвращать значение, никогда не поднимет исключение, и не будет выходить из процесса Python, если вы этого не хотите. Неважно, на каком порядке вы называете эти функции или программируете, сколько раз вы это называете, они всегда предсказуемы и могут быть зависеть от.

Что означает «в основном»?

Просто потому, что ваши функции работают все время, не означает, что ваше программное обеспечение работает. Пройдите неправильную переменную среды для контейнера Docker, Undstream API снижается, или, возможно, вы только что сделали математику неправильно. Вам все еще нужна единица, Fuzz, Tests Feature, формальные методы, если вы можете, и хорошее руководство по эксплуатации OLE, чтобы проверить работу вашего программного обеспечения. Не беспокойтесь о вашем программном обеспечении, взрывающиеся случайным образом, позволяет сосредоточиться на 100% на тех.

Кроме того, никакое количество FP не спасет вас от плохо отформатированного кода. Вам все равно нужны такие вещи, как Pylint, чтобы вы написали Печать («SUP») вместо Печать ("SUP)

Если это так очевидно, когда я _not_ сделать это?

В порядке приоритета:

  1. Когда вы исследуете идеи.
  2. Когда вы совершаете код среди тех, кто не обучен в ФП.
  3. Когда вы в срок.
  4. Когда вы модифицируете устаревший код без модульных тестов.

Очарование и розыгрыш Python это динамический язык. Несмотря на то, что не так прощение, как JavaScript, Lua или Ruby, он все еще позволяет много свободы играть с идеями, различными типами данных и обеспечивать различные способы эффективной работы кода на различных архитектурах инфраструктуры. С типами только принудительно (в основном) во время выполнения вы можете попробовать различные идеи, быстро запустите их, правильные ошибки, которые вы находите после запуска их, и повторите это, пока вы не заблокировали реализацию. Пока вы _can_ используете концепции FP для этого, если вы все еще учитесь, они могут замедлить вас. В других случаях это веселое время для изучения.

Сдача кода FP на репо Github, где другие не знакомы с FP, или не имеют никаких признаков, почему вы кодируете вещи, которые не кажутся Совместим к соучастию может действительно вызвать проблемы. Обычно команда принимает свои собственные правила, шаблоны и стили … и у них не всегда есть разумные причины. Лучше всего узнать, почему они кодируют то, как они делают вещи, и принимают эти стандарты. Если вы в состоянии преподавать команду, отлично, но FP довольно инопланет, уже имеет репутацию, чтобы быть тупой с ужасными евангелистами. Идти медленно здесь. Взрывное доверие в команде – один из способов гарантировать, что ваше программное обеспечение никогда не работает неправильно. Плохие рабочие отношения приводят к ужасному программному обеспечению.

Если вы находитесь в крайнем сроке, изучите что-нибудь новое, можете замедлить вас и рисковать, не ударяя его. В качестве альтернативы, это также гарантированный способ убедиться, что вы узнаете что-то быстро, хе.

FP или нет, вы не должны добавлять или изменять код в большой кодовой базе, за которой вы несете ответственность за, если у него нет модульных тестов. В противном случае у вас нет хорошей идеи, если вы что-то сломали, иногда в течение нескольких дней или недель. Добавьте тесты сначала, затем рефакторы вещей.

Функции, которые всегда работают: написание чистых функций

Чистые функции всегда работают. Они причины, что они всегда работают, это то, что они всегда возвращают значения. Они не вызывают исключения. Они технически не должны иметь побочные эффекты. Они желательны, потому что они всегда возвращают одинаковое значение, поэтому близки к математике, в том, что вы можете зависеть от их результата или «ответить». Устройство тестирования их также не требуют издеваний, только заглушки.

2 официальных правила идут так:

  1. тот же вход, тот же выход
  2. нет побочных эффектов

Возвращение Нет в порядке. Первая функция большинства Python Devs также представлена, Печать не возвращает ценность, как console.log в JavaScript. Тем не менее, это делает: Нет :

result = print("Sup")
print(result == None) # True

Обычно функция, которая не возвращает значения, либо Нет В случае Python считается функцией «без операции» или «NOOP» для короткого (произносится NO-OP). NOOP обычно являются признаком, в которой функция имеет побочные эффекты. NOOPS не являются чистыми функциями. Мы знаем, что Печать делает создание побочных эффектов; Вся точка призыва это состоит в том, чтобы изготовить побочный эффект записи на стандартную информацию, чтобы мы могли видеть, что делает HECK наш код.

Для занятий, однако, это более тонкие, и теперь вы знаете правила, вы увидите, что не так. Вот как вы прекратите проверять SSL Certs для отдыха, используя класс для обертывания урлыб :

import request.rest
import ssl

req = request.rest()
req.disable_ssl()
res = req.get("https://some.server.com")

Обратите внимание на disable_ssl () метод класса. Это не требует параметров и не возвращает значения. Почему? Вероятно, потому что, как и большинство классов, это изменяет настройку внутри в экземпляре класса, чтобы отключить материал SSL, чтобы следующий человек, который делает вызов для отдыха, не должен иметь подтвержденные сертификаты.

Вы делаете полную противоположность в функциональном программировании. Хотя в этом случае, вероятно, хорошо звонить disable_ssl () несколько раз без какого-либо вреда. Вещи как Получить более сложно.

Итак, нечистый Функция:

ssl = enabled

def get(url):
  return requests.get(url, ssl_enabled=ssl)

И а чистый Функция:

def get(ssl, url):
  return requests.get(url, ssl_enabled=ssl)

А также тот, который даже Более чистый , а блок тестирован:

def get(requests, ssl, url):
  return requests.get(url, ssl_enabled=ssl)

И Самая чистая функция, которую вы можете написать в Python по разумной форме :

def get(requests, ssl, url):
  try:
    result = requests.get(url, ssl_enabled=ssl)
    return result
  except Exception as e:
    return e

Напишите такие функции, и вы хорошо на пути к пониманию того, как Голанг написано.

Избегать ничего, используя Maybes

Python не предлагает большого количества гарантий, поэтому заставляет риск любителей, как это. Если вы пишете программное обеспечение, вы можете не захотеть риск. Есть 3 основных места, которые это происходит при вызове функций:

  1. Получение данных из словарей (потому что вы используете их сейчас, не классы, верно?)
  2. Получение данных из списков
  3. получать данные снаружи Python

Безопасные словари: возможно кортеж

Давайте поговорим о словарях.

Словари могут работать:

person = { firstName: "Jesse" }
print(person["firstName"]) # Jesse

Словари также могут потерпеть неудачу:

print(person["lastName"])
# KeyError: 'lastName'

Ват сделать!?

Вам нужно изменить, как вы думаете, Python 2-х способы. Во-первых, как вы безопасно доступаете в объекты, такие как использование Ключ в словаре или линзы. Во-вторых, как вы возвращаете значения из функций, таких как использование синтаксиса Golang, вернув несколько значений, которые позволяют вам знать, если функция работала или нет, или A, может быть, тип результата.

Вы можете безопасно получать доступ к словари, создав функцию GETTER:

def get_last_name(object):
  if "lastName" in object:
    return (True, object["lastName"], None)
  return (False, None, f"lastName does not exist in {object}")

Эта функция чиста и безопасна и будет работать с любыми данными, не выключающихся. Это также использует хороший трюк Python, когда вы возвращаете Кортеж (Список только на чтение) из функции; Вы можете разрушать его получить 3 переменных в церный синтаксис, что он чувствует, что он возвращает несколько значений. Мы выбрали что-то похожее на синтаксис Голанга, где они возвращаются Значение, ошибка мы возвращаемся DIDITWORK, VALUE, ОШИБКА Отказ Вы можете использовать синтаксис Golang, если хотите, я просто не люблю писать Если ошибка Отказ

ok, lastName, error = get_last_name(person)
if ok == False:
  return (False, None, f"Failed to get lastName from {person}")

Так что это ваш первый Может быть на сырьевом уровне. Это Кортеж Это содержит, если функция имела ваши данные или нет, данные, если это сделали, а если не почему. Примечание, если Хорошо это Ложь , ваша программа, вероятно, сделана в этот момент.

Разработчики рекомендуются создавать Исключения Для всего, что не обязательно исключительно, и поднимать Их, чтобы другие могли поймать их или разные типы и реагировать соответственно, обычно выше функционирующей цепочки. Проблема с этим вы не можете легко читать ваш код и увидеть ошибки, поскольку они могут быть исходями из совершенно разных файлов. Используя Mibes таким образом, очень понятно, какая функция не удалась, и ваша не должна обернуть вещи в попытки/поймать «на всякий случай».

Безопасные словари: Может быть, Тип

Кортеры в порядке, но имеют многолетний. Более короткий вариант – это, возможно, тип. Мы будем использовать Пимонада версия, потому что они сделали много тяжелой работы для нас. Сначала импортируйте это:

from pymonad.Maybe import *

Затем мы создадим наше getlastname Функция для возврата Может быть Тип вместо кортежа Как мы сделали раньше:

def get_last_name(object):
  if "lastName" in object:
    return Just(object["lastName"])
  return Nothing

Я говорю слово «тип», но в Python, он чувствует себя как функция. Заменить (True, Data, None) с Просто (данные) и (Ложно, Нет, Исключение («Причина»)) с Ничего Отказ Затем вы можете использовать его:

lastNameMaybe = get_last_name(person)

Вы первый инстинкт будет «крутым, если это Просто Как я могу получить свои данные? ». Ну, ты этого не делаешь.

“Wat!?”

Поверьте мне, мы осмотрим это в трубопроводной программировании ниже, на данный момент, просто знаю, что эта функция никогда не потерпит неудачу, и вы всегда получите Может быть Назад, убедитесь, что ваш код не бросает ошибки и является более предсказуемым и реализом.

Говоря о котором, вот Питиш :

def test_get_last_name_happy():
  result = get_last_name({'lastName': 'cow'})
  assert result == Just('cow')

“Wat…”

😁 Хорошо, пока не старишь удобнее, попробуйте это:

def test_get_last_name_happy():
  result = get_last_name({'lastName': 'cow'})
  assert result.value == 'cow'

Безопасные списки: может быть типа

То же самое можно сказать о Списки в питоне.

people = [{'firstName': 'Jesse'}]
first = people[0]

Прохладный.

people = []
first = people[0]
# IndexError: list index out of range

Неопытный Есть много способов сделать это; Вот QuickFix, вы получите многократное:

def get_first_person(list):
  try:
    result = list[0]
    return Ok(result)
  except Exception:
    return Nothing

Вы увидите, что это реализовано в более повторном использовании, как nth , кроме вместо возврата Нет это вернет Может быть :

def nth(list, index);
  try:
    result = list[index]
    return OK(result)
  except Exception:
    return Nothing

Чистые глубоко вложенные данные с использованием линз

Вы знаете, как сделать неразрушимые функции, делая их чистыми. Вы знаете, как получить доступ к Словари и Списки безопасно использовать Maybes Отказ

В реальных приложениях вы обычно получаете большие структуры данных, которые вложены. Как это работает? Вот несколько примерных данных, 2 человека с информацией о адресе:

people = [
  { 'firstName': 'Jesse', 'address': { skreet: '007 Cow Lane' } },
  { 'firstName': 'Bruce', 'address': { skreet: 'Klaatu Barada Dr' } }
]

Давайте безопасно получим адрес 2-го человека, используя Может быть :

def get_second_street(list):
  second_person_maybe = nth(list, 1)
  if isinstance(second_person_maybe, Just):
    address_maybe = get_address( second_person_maybe.value)
    if isinstance(address_maybe, Just):
      street_maybe = get_street(address_maybe.value)
      return street_maybe
  return Nothing

Да …… нет. Валовой. Многие заняли время, чтобы сделать это с лучшим, легче использовать API. Пыдаш имеет Получить Метод:

from pydash import get

def get_second_street(list):
  return get(list, '[1].address.skreet')

Круто, а? Работает на словарях, списках и оба объединены вместе.

Кроме … одна маленькая проблема. Если это не найдет ничего, он возвращает Нет Отказ Никто не приведет к исключениям времени выполнения. Вы можете предоставить по умолчанию в качестве параметра 3RD. Мы уничтожим это с Может быть ; Менее красивое, но моар сильный и чистый.

def get_second_street(list):
  result = get(list, '[1].address.skreet')
  if result is None:
    return Nothing
  return Just(result)

Возвращая ошибки вместо повышения исключений

Словари и массивы, не имеющие данные в порядке, но иногда вещи действительно разбиваются или не работают … Что мы делаем без исключения? Мы возвращаем Результат Отказ У вас есть 2 варианта на том, как вы это делаете. Вы можете использовать Кортеж Мы показали вам выше, делая это Голанг стиль:

def ping():
  try:
    result = requests.get('https://google.com')
    if result.status_code == 200:
      return (True, "pong", None)
    return (False, None, Exception(f"Ping failed, status code: {result.status_code}")
  except Exception as e:
    return (False, None, e)

Тем не менее, существуют преимущества для использования истинного типа, который мы покажем позже в трубопроводном программировании. Пимонад имеет общее название Либо , но Левый а также Правильно не иметь смысла, поэтому я сделал свое собственное звание Результат Основываясь на результате JavaScript Folktale, потому что «ОК» и «Ошибка» – это слова, люди понимают, и связывают с функциями, работающими или ломающимися. Влево и вправо похожи на … вождение … или твои руки … или уныло … или игры … или что-то кроме программирования.

def ping():
  try:
    result = requests.get('https://google.com')
    if result.status_code == 200:
      return Ok("pong")
    return Error(Exception(f"Ping failed, status code: {result.status_code}"))
  except Exception as e:
    return Error(e)

Вам не нужно ставить исключения в Ошибка . ; Вы можете просто поставить строку. Мне нравятся исключение, потому что у них есть полезные методы, информация, информация о трассировке стека и т. Д.

Программирование трубопроводов: строить неразрывные программы

Вы знаете, как построить Чистые функции которые не ломаются. Вы можете безопасно получить данные, которые не имеют гарантии, что это будет там, используя Мэйбес и Линзы Отказ Вы можете вызвать функции, которые выполняют побочные эффекты, такие как HTTP-запросы, файлы для чтения или анализа пользовательских входных строк безопасно, возвращая Полученные результаты . У вас есть все основные инструменты функционального программирования .. Как вы создаете функциональное программное обеспечение?

Составив функции вместе. Есть множество способов сделать это чисто. Чистые функции не ломаются. Вы создаете более крупные функции, которые являются чистыми, которые используют эти чистые функции. Вы продолжаете делать это, пока не появится программное обеспечение.

Подожди … Что вы подразумеваете под «состоим»?

Если вы из объектно-ориентированного фона, вы можете подумать о составлении как противоположность наследования; Использует экземпляры классов внутри другого класса. Это не то, что мы имеем в виду здесь.

Давайте разобраться на некоторых JSON! Цель состоит в том, чтобы отформатировать имена людей из большого списка словарей OLE. При этом вы узнаете, как составить функции. Хотя это не чистые, концепция одинакова.

Вот, наша строка JSON:

peopleString = """[
    {
        "firstName": "jesse",
        "lastName": "warden",
        "type": "Human"
    },
    {
        "firstName": "albus",
        "lastName": "dumbledog",
        "type": "Dog"
    },
    {
        "firstName": "brandy",
        "lastName": "fortune",
        "type": "Human"
    }
]"""

Сначала мы должны разобрать JSON:

def parse_people(json_string):
  return json.loads(json_string)

Следующим, нам нужно фильтровать только людей в Список нет собак.

def filter_human(animal):
  return animal['type'] == 'Human'

И так как у нас есть Список , мы будем использовать этот предикат в Фильтр Функция из пидаш:

def filter_humans(animals):
  return filter_(animals, filter_human)

Далее мы должны извлечь имена:

def format_name(person):
  return f'{person["firstName"]} {person["lastName"]}'

А потом сделать это на все предметы в Список ; Мы будем использовать карта от пидаш за это:

def format_names(people):
  return map_(people, format_name)

Наконец, нам нужно прописные имена, поэтому мы карта еще раз и start_case Из пидаш:

def uppercase_names(people):
  return map_(people, start_case)

Отлично, куча функций, как вы используете их вместе?

Гнездо

Вложенность является наиболее распространенным.

def parse_people_names(str):
  return uppercase_names(
    format_names(
      filter_humans(
        parse_people(str)
      )
    )
  )

Ой … Вот почему вы часто слышите «Birds Nest», являющиеся негативной коннотацией, чтобы описать код.

Поток

Пока пидаш и Лодаш называют это поток , это более распространенный способ построить большие функции из более мелких через их составляющие и дает вам ваше первое представление о программировании стиля «трубопровод».

parse_people = flow(parse_people, filter_humans, format_names, uppercase_names)

Трубопровод: Пимонад версия

Теперь поток довольно приятно, но, надеюсь, вы увидели некоторые проблемы. В частности, ни один из этих функций не является супер чистым. Да, тот же вход, тот же выход и без побочных эффектов … но что происходит, когда один из них возвращает Ничего ? Когда происходит, если вы делаете опасные вещи, и один возвращает Результат который содержит Ошибка . вместо того Хорошо ?

Ну, каждый из этих типов адапторных, сделанных для трубы вместе. Вы видели, как создали функции для поток работал вместе; Им просто нужно 3 правила:

  1. быть в основном чистой функцией
  2. иметь один вход
  3. вернуть вывод

Может быть и Результат Может также подключиться вместе, но у них есть несколько дополнительных особенностей. Единственный 4, который мы заботимся о этой статье:

  1. Если Может быть Получает Просто Это достаточно умно, чтобы получить Просто (вещь) .value и передать его следующей функции. Результат одинаково развернуто значение в Хорошо и и передавать его к следующей функции.
  2. Каждый должен вернуть один и тот же тип обратно. Если вы цепь Может быть вместе, как вы делаете в поток тогда ожидается, что вы вернете свой Просто (вещь) или Ничего Отказ
  3. Оба обрабатывают плохие вещи. Если цепочка Может быть внезапно получает Ничего вся вещь даст вам Ничего Отказ Если какая-либо из функций, которые вы подключены вместе, получите Результат И вдруг один получает Ошибка . В цепочке вся цепь получает Ошибка . Отказ
  4. У них есть поток встроенный; Но вместо того, чтобы называть его, вы используете странные, новые, но не-питовые символы, чтобы сбить вас с толку, выглядеть впечатляющим и заставить код чувствовать себя менее Verbose, несмотря на повышенную активность мозга.

Это много, игнорируйте это. Просто посмотрите на пример:

def parse_people_names(str):
  return parse_people(str) \
  >> filter_humans \
  >> format_names \
  >> uppercase_names

Прощай! 👋🏼.

Если это немного инопланет и странно, это потому, что:

  • Вы выполняете функциональное программирование в ориентированном объекте + императивный язык; ты жжешь!
  • >> Разве не пифинируют не совместимые ®
  • Большинство Python Devs видят \ и думать “AW Man, этот код слишком длинный …”
  • «… подожди, вы накладываете там функции, но не вызывая их, ни отдавая им параметры, Что в … “

Вот почему многие функциональные программисты приятно, даже если они не такие великие евангелисты. Многие не FP предназначены, люди видят такого типа кода, урегулирования и ухода. Это делает много FP’ES одиноко, поэтому они более чем рады быть сердечными и вежливыми, когда люди говорят с ними в сообществе программирования.

Ручной трубопровод

Помните, что неприятный пример получения глубоко вложенных свойств перед выученными линзами? Давайте заменим это с помощью трубопровода, используя Может быть ; Это даст вам лучшее чувство, как эти вещи подключены вместе, как поток выше.

def get_second_street(list):
  second_person_maybe = nth(list, 1)
  if isinstance(second_person_maybe, Just):
    address_maybe = get_address( second_person_maybe.value)
    if isinstance(address_maybe, Just):
      street_maybe = get_street(address_maybe.value)
      return street_maybe
  return Nothing

Валовой. Хорошо, давайте начнем с вершины, сначала нам нужна фамилия (Кстати, я рад, что вы проигнорировали «до свидания» и все еще здесь, у вас есть то, что нужно, о да):

def get_second_person(object):
  return nth(object, 1)

Cool, Next Up, получите адрес:

def get_address(object):
  if 'address' in object:
    return Just(object['address'])
  return Nothing

Наконец, получите Dat Skreet Skreet!

def get_street(object):
  if 'skreet' in object:
    return Just(object['skreet']
  return Nothing

Теперь давайте составь их вместе.

def get_second_street(object):
  second_person_maybe = get_second_person(object)
  if isinstance(second_person_maybe, Nothing):
    return Nothing

  address_maybe = get_address(second_person_maybe.value)
  if isinstance(address_maybe, Nothing):
    return Nothing

  street_maybe = get_street(address_maybe)
  if isinstance(street_maybe, Nothing)
    return Nothing

  return street_maybe

Эсх … Хорошо, давайте проверим ее:

second_street_maybe = get_second_street(people)

Обратите внимание на пару вещей. Каждый раз, когда вы вызываете функцию, вы осмотрите, если возвращаемое значение является Ничего Отказ Если это так, вы немедленно просто верните это и прекратите бегать все остальное. В противном случае вы называете следующий в цепочке и разверните значение. Здесь мы делаем это вручную через может быть . Кроме того, Вернуть Street_maybe. в конце немного избыточно; Нет необходимости проверять на Ничего Там просто верните его, но я хотел, чтобы вы увидели повторяющуюся модель 3 раза.

Этот шаблон это то, что >> делает для вас: проверяет Ничего И прервать рано, а также разворачивает ценность и дает функцию в цепочке. Переписать его использование оператора связывания:

def get_second_street(object):
  return get_second_person(object) \
  >> second_person_maybe \
  >> get_address \
  >> get_street

Легко забыть \. Это потому, что Python Super Strict на пробере и только изредка позволяет вам делать разрывы линии с кодом. Если вы не хотите использовать это, просто поставьте ее все на 1 строку:

def get_second_street(object):
  return get_second_person(object) >> second_person_maybe >> get_address >> get_street

Ручной результат трубопровод

Давайте сделаем некоторое опасное дерьмо. Мы собираемся загрузить наш ключ шифрования от AWS, затем извлеките наш токен OAUTH, затем загрузите в список кредитных продуктов из API, который требует этого токена, и, наконец, не хватает только что ID.

Опасные вещи? Потенциальные исключения? Работа для Результат Отказ

Получить ключ DAT:

def get_kms_secret():
  try:
    result = client.generate_data_key(
      KeyId='dev/cow/example'
    )
    key = base64.b64decode(result['Plaintext']).decode('ascii')
    return Ok(key)
  except Exception as e:
    return Error(e)

Не волнуйтесь, если вы не знаете, что чертовски Кмс Это просто все шифрование Amazon, и дает вам ключи, которые вам разрешено получать. Если вы не, эта функция не удастся. Это просто дает нам временный частный ключ шифрования в качестве текста. Мы будем использовать это, чтобы получить наш токен ОАУТ.

Далее, получите токен ОАУТ через Запросы библиотека:

def get_oauth_token(key):
  try:
    response = requests.post(oauth_url, json={'key': key})
    if response['status_code'] == 200:
      try:
        token_data = response.json()
        return Ok(token_data['oauth_token'])
      except Exception as parse_error:
        return Error(parse_error)
    return Error(Exception(response.text))
  except Exception as e:
    return Error(e)

У вас есть выбор стиля здесь. Если вы посмотрите выше, существует 4 потенциальных сбоя: код состояния, не являющийся 200, не разбежив JSON, не в состоянии найти токен OAUTH в Parsed JSON, или ошибка сети. Вы можете просто «обрабатывать все это в той же функции», как я сделал выше. Точка смещения его вместе – «Я получил токен или нет?». Однако, если вам не нравится вложенные IFS и Trys Затем вы можете разделить это в 4 функция, каждый из которых принимает Результат Также проводит их вместе в порядке.

Теперь, когда у нас есть наш токен, давайте назовем последнее API, чтобы получить список кредитных продуктов. Мы получим список потенциально, но все, что мы хотим, это идентификатор, поэтому мы рассмотрим, как выключить:

def get_loan_ids(token):
  try:
    auth_header = {'authentication': f'Bearer {token}'}
    response = requests.get(loan_url, headers=auth_header)
    if response.status_code == 200:
      try:
        loans = response.json()
        ids = map_(loans, lambda loan: get(loan, 'id', '???'))
        return Ok(ids)
      except Exception as e:
        return Error(e)
    return Error(Exception(response.text))
  exception Exception as overall_error:
    return Error(overall_error)

Если все пойдет хорошо, вы получите список строк. В противном случае и ошибка. Давайте провод все 3 вверх:

def get_loan_ids():
  return get_kms_secret() \
  >> get_oauth_token \
  >> get_loan_ids

Когда ты пойдешь:

loan_ids_result = get_load_ids()

Либо это работает, и что loan_ids_result это Хорошо или не удалось где-то там И это Ошибка . содержащий исключение или текст ошибки.

… Теперь, один чит, который я сделал, и вы добро пожаловать, чтобы смешать и совпадать Мэйбес и Результаты вместе. Вы видите, когда мы пытаемся получить удостоверение личности ссуды?

get(loan, 'id', '???')

Этот 3-й параметр – это значение по умолчанию, если свойство не там или IS Нет Отказ _Right_ вещь, которую нужно сделать, это использовать Может быть вместо. Вы можете быть прагматичным, подобным этим, если вы хотите, просто будьте в курсе, это типы вещей, которые вы увидите, где «код не имеет ошибок, но не работает» 🤪. Кроме того, я склонен к …| Ошибки больше чем Ничего В этих сценариях, потому что они дают вам возможность обеспечить исключение или текст с большим количеством контекста относительно того, почему. Почему огромный для программиста, особенно когда вы близорутесь к ошибке и знаете, почему он, вероятно, не удалось в большом наборе функций, которые все могли сломаться.

Выводы

Функции в порядке, но исключения могут вызвать много косвенного нарушения. Смысл, вы думаете, что вы знаете 3 способа функции, или даже программа может потерпеть неудачу, но затем еще одно неожиданное исключение исходит от какой-либо другой глубоко вложенной функции. Полностью удалить их и запирать те, которые вы знаете, или не знаю, взорвется, используя попробуйте/поймать через Чистые функции Удаляет эту проблему для вас. Теперь вы знаете на самом деле, какие пути возьмут ваши функции. Это сила чистых функций.

Однако это не защищает вас от использования NULL ( I.E. Нет ) данные. Вы получите все виды исключений выполнения в функциях, которые ожидают хороших данных. Если вы заставляете все свои функции, чтобы справиться с этой случайностью через Мэйбес Затем вы никогда не получаете нулевые указатели. Это включает в себя использование Линзы Доступ к глубоко вложенным данным.

После того, как вы выйдете за пределы вашей программы по боковым эффектам, таким как отдохнуть вызовы, чтение файлов или анализа данных, все могут пойти не так. Ошибки в порядке, и хорошо, и образовательные. Наличие функции возвращает A Результат вместо поднятия Исключение Как вы убедитесь, что функция чистая. Вы также можете прервать рано, если возникнут проблема VS, имеющих каскадные эффекты с другими функциями, не имеющие их данные в том, что им нужно. Ты тоже, как Голанг и Ржавчина , имейте возможность документировать, какая ошибка там, где это происходит с полезным контекстом против угадания в длинном трассировке стека.

Наконец, после того, как вы написали чистые функции, вы можете построить большие чистые функции, которые составляют их вместе. Вот как вы строите чистое программное обеспечение через Программирование трубопроводов (Также называется Железнодорожное программирование , стиль потоковой передачи и т. Д.).

Python предоставляет Пидаш Библиотека, чтобы дать вам основы чистых функций с работой с данными и списками. Пимонад Предоставляет основы в создании Может быть и Либо (Что я вызываю результатом). Если вы заинтересованы, есть Язык кокосового программирования Это объединяет и компилирует Python, позволяя вам писать в более функциональном стиле программирования. Вот вкус снова написал наш пример выше:

def get_loan_ids():
  return get_kms_secret()
  |> get_oauth_token
  |> get_loans
  |> map( .id )

Не волнуйтесь, если все это кажется подавляющим. Функциональное программирование – это совершенно другой способ мышления, Python не является функциональным языком, и все это все супер продвинутые концепции, которые я просто охватил основы. Просто тренируйте чистые функции и пишущие тесты для них. Как только вы получите основы этого, вы начнете чувствовать, как Spidey Sense, когда что-то нечистое и имеет побочные эффекты. С помощью Maybes вы сначала понравились их, а затем понимаете, как только вы начнете использовать их ответственно, насколько дополнительная работа вы должны сделать, чтобы избежать нулевых указателей. Evithers/Результаты могут быть сложными для отладки сначала, поскольку вы не будете распадаться через Stacktlaces, и вы узнаете, какие сообщения об ошибках лучше всего писать, и как захватывать различные сбои. Придерживайтесь этого, все в порядке, если вы используете только немного; Маленькое использование, которое все равно поможет вашему коду более солидно.

Оригинал: “https://dev.to/jesterxl/write-unbreakable-python-20ck”