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

Сравнение менеджеров C ++ Raii и Python

Я читал на практике в C ++, называемых ресурсами, приобретает инициализацию или райи, после … Теги с Python, CPP, программированием.

Я читал на практике в C ++ под названием Приобретение ресурсов является инициализация или Райи , услышав об этом на подкасте. Я в основном проводил свое время программирование в Python, и это заставило меня подумать о Контекстные менеджеры и с Заявление в Python. И RAII, так и контекстные менеджеры являются методами для обеспечения выпуска ресурса, когда вы оставляете текущий объем.

Данное назад я смотрел поговорить Python, как ограничивающий корпус C ++ по Брэндон Родос Где он сравнивает Python к C ++. Я рекомендую вам просмотреть разговор, так как это интересный способ изучения питона. Я бы суммировал предпосылку как следующее, используя одинаковое сравнение, что и автор: Поскольку круг – это ограничивающий случай многоугольника, когда количество ребер идет до бесконечности, а также Python ограничивающий случай C ++ при получении лучших идей C ++ к их крайностям.

С помощью в качестве фона, я добавлю еще один пример того, как Python действительно может быть предельный случай C ++. Как уже упоминалось во введении, сообщество C ++ нашла Raii в качестве хорошего метода для освобождения ресурсов. Но прежде чем попасть в Райи, какой ресурс? Это может быть много разных вещей, но в этом контексте это все, что должно быть приобретено и выпущено. В C ++ это можно выделить память на куче, то, о чем мы пифисты не должны думать. Тем не менее, это также может быть файл, сокет, база данных сеанса или Mutex-Lock. Все эти и многие другие примеры существуют как в Python, так и в C ++.

Теперь, что такое Раи? Это практика, когда ресурс связан с течением жизни объекта. Это делается путем определения класса, в котором ресурс приобретается в конструкторе и выпущено в деструктор. Когда вы создаете экземпляр этого класса, ресурс будет связан с этим экземпляром, пока он не будет уничтожен. Если вы не используете вручную/динамически выделите новый экземпляр, он будет уничтожен после того, как оставлял текущий объем. Это делает его действительно удобным, так как в C ++ вы можете просто приложить кусок кода в курчавых скобках для создания нового объема. Однако для этого на работе есть одно окончательное условие для класса Raii. Разрушитель не разрешается повышать ошибку, так как он должен закончить, чтобы гарантировать, что ресурс выпускается. Во вступлении я связал Эта страница на Raii На CPPreference.com, который имеет описание практики. У них также есть хороший пример, сравнивая код Raii VS Non-Raii C ++ для замков, поэтому, если вы хотите, чтобы пример, я рекомендую вам проверить это. Однако для этого поста самая важная часть, чтобы понять о Раи, это то, что:

  • Raii позволяет разработчикам C ++ убедитесь, что ресурс выпускается при выходе из текущего объема. Когда программа покидает масштабы, независимо от того, что, даже если это через раннее возвращение или повышение исключения, ресурс освобождается.

Sidenote: CPPreference – мой любимый ресурс для документации C ++ и хорошим местом для начала, если вы заинтересованы в Diving Heell в Raii.

Независимо от того, есть ли вы приправленные Pythonista или относительно новы на языке, если вы когда-либо работаете с файлами, вы, вероятно, написали что-то подобное:

with open("my_file.txt", "r") as my_file:
    my_data = my_file.read()

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

Создание собственного менеджера контекста также довольно проста. Либо вы делаете это, создавая класс, который определяет методы __enter__ и __exit__ или используя ContextManager декоратор. Я буду использовать первый метод для этого примера, поскольку это делает сравнение с Raii Clear. Тогда мы можем создать Самопотаживающий Tempfile Context Manager (который, конечно, чрезвычайно полезен), как это:

from tempfile import TemporaryFile

class PrintingTempFileContext:
    def __enter__(self):
        print("")
        self.file = TemporaryFile(mode="w+t")
        return self.file

    def __exit__(self, exception_type, exception_value, traceback):
        print(f"")
        self.file.seek(0)
        print(self.file.read())
        self.file.close()
        print("")

Запуск этого кода:

with PrintingTempFileContext() as tempfile:
    tempfile.write("Hello DEV!")

Вывод:



Hello DEV!

Теперь, что произойдет, если мы подняли ошибку внутри менеджера контекста? Давайте попробуем запустить это:

with PrintingTempFileContext() as tempfile:
    tempfile.write("Hello DEV!")
    raise RuntimeError

Вывод:


 - exception_value=RuntimeError() - traceback=>
Hello DEV!

Traceback (most recent call last):
  File ".../print_tempfile_context.py", line 19, in 
    raise RuntimeError
RuntimeError

Метод __exit__ все еще вызывается, и файл закрыт. Так что независимо от того, как мы выходим на сферу объема контекстно-менеджера, очистка будет запущена. Это звучит очень много, как использовать Raii-класс внутри масштаба, не так ли? Я сказал, что я выбрал этот метод реализации контекстно-менеджера как легче сравнить с Raii. Это связано с тем, что метод __enter__ и конструктор класса Raii делают тот же тип работы. Они оба связывают ресурс, который мы хотим приобрести, в этом примере экземпляра Временноеfile Отказ Аналогично, метод __exit__ делает то же самое, что и деструктор класса Raii. Следовательно, также важно, чтобы метод __exit__ не повышает ошибку. Подобно деструктору класса Raii, это может привести к выпуску ресурса, не выходящую после оказания объема.

Заключить, я хочу ответить на то, как это относится к разговору, Python в качестве ограничения C ++ . Моя надежда заключается в том, что я показал, как контекстные менеджеры и Raii очень похожи в том, как они решают проблему управления ресурсами. Кроме того, контекстные менеджеры построят на практику Raii, имея выделенный синтаксис, с -утверждение. Поэтому я утверждаю, что контекстные менеджеры являются ограничивающим случай Raii. Поскольку на практике собственный синтаксис является одним из самых простых способов программного языка должен одобрить практику. Таким образом, это добавляет еще один аргумент, к тем, которые даны Брэндон Родос, к тому, почему Python является предельным случаем C ++.

Оригинал: “https://dev.to/fronkan/comparing-c-raii-and-python-context-managers-50eg”