Библиотека Python разработчика | Книги по питону
18.3K subscribers
1.05K photos
403 videos
82 files
1.15K links
Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍

По всем вопросам @evgenycarter

РКН clck.ru/3Ko7Hq
Download Telegram
В Python функция range() определяет все целые числа в полуоткрытом интервале.
То есть range(2, 10) математически означает [2, 10),
или, говоря на языке Python: [2, 3, 4, 5, 6, 7, 8, 9].

Несмотря на асимметрию, это не ошибка и не случайность.
В этом есть логика: такой подход позволяет "склеивать" два соседних интервала без риска ошибиться на единицу:

[a, c) = [a, b) + [b, c)

Для сравнения, если бы использовались закрытые интервалы, получалось бы так:

[a, c] = [a, b] + [b+1, c]

Эта же идея объясняет, почему индексация начинается с нуля:
[0, N) содержит ровно N элементов.

Эдсгер Дейкстра написал на эту тему отличную статью ещё в 1982 году.

📲 Мы в MAX

👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2
Условное использование менеджеров контекста обычно доставляет неудобства: нельзя просто разместить with внутри блока if, не заключив туда весь блок with. Это часто приводит к дублированию кода:


def print_whole_file(
*,
path: Optional[str] = None,
file_obj: Optional[TextIO] = None
):
assert path or file_obj

if path:
with open(path) as f:
print(f.read(), end='')
else:
print(file_obj.read(), end='')


Способ борьбы с этой проблемой — использовать ExitStack и вызывать enter_context внутри if:


def print_whole_file(
*,
path: Optional[str] = None,
file_obj: Optional[TextIO] = None
):
assert path or file_obj

with ExitStack() as stack:
if path:
file_obj = stack.enter_context(
open(path)
)

print(file_obj.read(), end='')


Однако более очевидный способ достичь того же — использовать тривиальные менеджеры контекста, которые ничего не делают, когда они не нужны, вместо «настоящих». Начиная с Python 3.7, их можно получить с помощью contextlib.nullcontext:


def print_whole_file(
*,
path: Optional[str] = None,
file_obj: Optional[TextIO] = None
):
assert path or file_obj

if path:
context = open(path)
else:
context = nullcontext(file_obj)

with context as f:
print(f.read(), end='')


📲 Мы в MAX

👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3