PEP: https://peps.python.org/pep-0661/
Код: https://github.com/python/cpython/pull/148831
Обсуждение: https://discuss.python.org/t/pep-661-sentinel-values/9126
В питон 3.15 добавляют новый
builtin – sentinel, чтобы создавать значения по-умолчанию.Проблема достаточно понятная, например: нам нужно создать какое-то значение по-умолчанию, чтобы мы знали, что аргумент не был передан. Но
None является валидным значением в нашей логике. Потому нужно создать новое особое "пустое" значение.Данная логика встречается буквально везде:
• dataclasses
• django_modern_rest
• msgspec (тоже самое но на C)
Однако, теперь можно упростить АПИ для создания таких объектов до:
_SENTINEL_VALUE = sentinel('_SENTINEL_VALUE')
А вот пример PR, где в
dataclasses уже используют новое АПИ: https://github.com/python/cpython/commit/16952218d0535904236e8a39851133688c9ce1f0Как оно примерно внутри устроено
Как и все билтины,
sentinel написан на C, его исходники вот тут: https://github.com/python/cpython/blob/main/Objects/sentinelobject.cНо я приведу примерную версию на питоне (из PEP), чтобы было понятнее, как он работает внутри:
class sentinel:
__slots__ = ("__name__", "_module_name")
def __init_subclass__(cls):
raise TypeError("type 'sentinel' is not an acceptable base type")
def __init__(self, name, /):
if not isinstance(name, str):
raise TypeError("sentinel name must be a string")
self.__name__ = name
self._module_name = sys._getframemodulename(1)
@property
def __module__(self):
return self._module_name
def __repr__(self):
return self.__name__
def __reduce__(self):
return self.__name__
def __copy__(self):
return self
def __deepcopy__(self, memo):
return self
def __or__(self, other):
return typing.Union[self, other]
Хороший пример синглтона ^
Что здесь важно?
1.
pickle должен корректно работать, для того имя sentinel('NAME') должно совпадать с именем объекта на уровне модуля: NAME = 2. Объект должны быть внешне иммутабельным
3. Копирование объекта должно возвращать тот же самый синглтон
Не только для Питона
Ну и конечно же: есть две новые функции в C-API для создания таких объектов в C-extensions (как
msgspec например): •
PyObject *PySentinel_New(const char *name, const char *module_name) для создания•
bool PySentinel_Check(PyObject *obj) для проверкиВот такая фича. Довольно просто, закрывает понятную проблему. Но не очень ясно, почему builtin.
Обсуждение: Приходилось ли пользоваться чем-то подобным? Какую реализацию синглтона в питоне вы считаете лучшей? Согласны с добавлением нового builtin?
| Поддержать | YouTube | GitHub | Чат |