#python
Я позволю себе украсть идею у Дэна Байдера, чью книгу я сейчас читаю и запустить серию мыслей по поводу программирования на Python. Для меня это одновременно конспект и рефлексия на тему содержания книги, а вам просто может быть интересно.
И первая тема: менеджеры контекста и инструкции with.
Наверняка вы хоть раз писали что-то типа
with open("model.pickle", "br") as f:
model = pickle.read(f)
Это стандартный путь работы с файлами в python. Зачем так делать? Чтобы гарантировать закрытие контекста файла. В файлах используются специальные дескрипторы, и если их не поставить, то файл может поламаться.
Эта штука называется контекстом. Открытие файла - открывает контекст f, а функция f.close(). И вот чтобы не париться со всем этим есть конструкция менеджера контекста и инструкция with которая упрощает работу с ним.
Такие же приколы есть например с БД, где коннект имеет контекста, и его необходимо закрывать, например, чтобы освободить пулл коннектов.
Вы можете мутить свои менеджеры контекстов, взаимодействующие с
Есть и другой способ. Его просто примером покажу. Там декоратор и фабричная функция. Подходы эквивалентны выбирать, отталкиваясь от кодстайла.
Я позволю себе украсть идею у Дэна Байдера, чью книгу я сейчас читаю и запустить серию мыслей по поводу программирования на Python. Для меня это одновременно конспект и рефлексия на тему содержания книги, а вам просто может быть интересно.
И первая тема: менеджеры контекста и инструкции with.
Наверняка вы хоть раз писали что-то типа
with open("model.pickle", "br") as f:
model = pickle.read(f)
Это стандартный путь работы с файлами в python. Зачем так делать? Чтобы гарантировать закрытие контекста файла. В файлах используются специальные дескрипторы, и если их не поставить, то файл может поламаться.
Эта штука называется контекстом. Открытие файла - открывает контекст f, а функция f.close(). И вот чтобы не париться со всем этим есть конструкция менеджера контекста и инструкция with которая упрощает работу с ним.
Такие же приколы есть например с БД, где коннект имеет контекста, и его необходимо закрывать, например, чтобы освободить пулл коннектов.
Вы можете мутить свои менеджеры контекстов, взаимодействующие с
with для этого нужно реализовать функции __enter__(self) для открытия контекста и __exit__(self, exc_type, exc_val, exc_tb) для закрытия. Есть и другой способ. Его просто примером покажу. Там декоратор и фабричная функция. Подходы эквивалентны выбирать, отталкиваясь от кодстайла.
from contextlib import contextmanager
@contextmanager
def managed_file(name):
try:
f = open(name, 'w')
yield f
finally:
f.close()
#python
Ещё немного снипитов кода упертых из книги Дэна Байдера.
Я не знал, что при возвращение внутренней функции, она запоминает состояние внешней. Теперь знаю, даже представил себе, как это работает.
Вот пара примеров:
Здесь запоминается текст, переданный при получении внутренней функции.
Вот еще наглядный пример:
Практическое применение - создание фабрики функций. По сути внешняя конфигурирует внутреннюю. Возможность интересная и, вероятно, в определенных обстоятельствах полезная. Я же обычно предпочитаю делать объекты-калькуляторы. У которых состояние конфигурируется через внутренние атрибуты и есть метод расчёта
Ещё немного снипитов кода упертых из книги Дэна Байдера.
Я не знал, что при возвращение внутренней функции, она запоминает состояние внешней. Теперь знаю, даже представил себе, как это работает.
Вот пара примеров:
def get_speak_func(text, volume):
def whisper():
return text.lower() + '...'
def yell():
return text.upper() + '!'
if volume > 0.5:
return yell
else:
return whisper
>>> get_speak_func('Привет, Мир', 0.7)()
'ПРИВЕТ, МИР!'
Здесь запоминается текст, переданный при получении внутренней функции.
Вот еще наглядный пример:
def make_adder(n):
def add(x):
return x + n
return add
>>> plus_3 = make_adder(3)
>>> plus_5 = make_adder(5)
>>> plus_3(4)
7
>>> plus_5(4)
9
Практическое применение - создание фабрики функций. По сути внешняя конфигурирует внутреннюю. Возможность интересная и, вероятно, в определенных обстоятельствах полезная. Я же обычно предпочитаю делать объекты-калькуляторы. У которых состояние конфигурируется через внутренние атрибуты и есть метод расчёта
calc(self, *args). Мне кажется такой подход более явным , а Явное лучше, чем неявное.
👍2