Что это такое и как их использовать

Что такое значение Sentinel?

Сигнальное значение — это специальное значение, используемое для обозначения различных вещей, таких как отсутствие необязательных входных данных от пользователя или необходимость завершения цикла (или программы) или то, что во время операции поиска не было найдено ничего важного. Здесь важно отметить, что выбранное контрольное значение не должно перекрываться с «достоверными» данными (например, если допустимые данные являются положительными целыми числами, контрольное значение не должно быть … положительным целым числом).

Наиболее очевидным примером в Python будет None. Он почти всегда используется как значение по умолчанию, когда для необязательного аргумента не задано никаких входных данных. Другой пример: при попытке .get что-то из словаря, которого не существует, вы получите обратно значение None — что вы будете с ним делать, зависит только от вас.

Использование объектов Sentinel

Итак, на данный момент вы можете подумать, что None — отличный вариант для часового, и в большинстве случаев это так. Однако что делать, если None также является частью допустимых данных?

weather_journal = {
  '2023-04-01': 'Rain and wind - broke my umbrella',
  '2023-04-02': 'Sunny',
  '2023-04-03': None,  # no comments - playing video games all day in a dark room
  '2023-04-04': 'Sunny'
}

obs_a = weather_journal.get('2023-04-03')  # no comments
obs_b = weather_journal.get('2023-04-25')  # no key for 2023-04-05 because it's in the future

В приведенном выше примере и obs_a, и obs_b будут None, но 2023-04-03 имеет запись в журнале, а 2023-04-25 — нет. Нам нужно что-то еще, чтобы помочь нам различать их. Мы можем сделать что-то похожее на [1] и определить новый объект, который будет использоваться для указания того, что дата еще не добавлена ​​к weather_journal.

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

Обратите внимание, что мы используем оператор is, потому что хотим проверить подлинность объекта, а не его значение.

Другие примеры

Если вы играли с dataclasses в Python, вы могли встретить некоторые контрольные значения, такие как dataclasses.MISSING, используемые для обозначения отсутствующего значения по умолчанию — None является допустимым значением по умолчанию, поэтому они не могут его использовать — и dataclasses.KW_ONLY используется для отметки поля только для ключевых слов.

Другой пример — встроенный в Python iter. Вы можете изменить его поведение, передав значение Sentinel.

STOP_RANDOM_STUFF = object()

def get_random_stuff():
  return np.random.choice([1, 2, 3, STOP_RANDOM_STUFF], size=1)[0]

list(iter(get_random_stuff, STOP_RANDOM_STUFF))
# example result: [1, 3, 2, 3, 1, 3]

Когда iter передается значение дозорного, он будет вызывать первый аргумент, в нашем случае get_random_stuff, пока не вернет дозорный, то есть STOP_RANDOM_STUFF.

Заключение

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



Рекомендации

[1] https://python-patterns.guide/python/sentinel-object/

[2] https://www.revsys.com/tidbits/sentinel-values-python/

[3] https://ianbicking.org/blog/2008/12/the-magic-sentinel.html

[4] https://en.wikipedia.org/wiki/Sentinel_value

Ещё от того же автора: