Pythonic способ сочинять контекстные менеджеры для объектов, принадлежащих классуPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Pythonic способ сочинять контекстные менеджеры для объектов, принадлежащих классу

Сообщение Anonymous »

Типично для некоторых задач несколько объектов, которые имеют явные ресурсы, которые должны быть явно выпущены - скажем, два файла; Это легко выполнять, когда задача локально для функции с использованием вложенных с блоками или - даже лучше - один с блоком с несколькими with_item положениями:

Код: Выделить всё

with open('in.txt', 'r') as i, open('out.txt', 'w') as o:
# do stuff
< /code>

OTOH, я все еще изо всех сил пытаюсь понять, как это должно работать, когда такие объекты не просто локальны для функции, но принадлежащий экземпляру класса - другими словами, как контекстные менеджеры составляют. < /p>

Идеально я хотел бы делать что -то вроде: < /p>

Я хотел бы делать что -то вроде: < /p>

  < /p>

.class Foo:
def __init__(self, in_file_name, out_file_name):
self.i = WITH(open(in_file_name, 'r'))
self.o = WITH(open(out_file_name, 'w'))
и попросить Foo само по себе превращение в диспетчер контекста, который обрабатывает i и o , так что когда я делаю

Код: Выделить всё

with Foo('in.txt', 'out.txt') as f:
# do stuff
< /code>

self.i< /code> и self.o < /code> позаботится автоматически, как и следовало ожидать.class Foo:
def __init__(self, in_file_name, out_file_name):
self.i = open(in_file_name, 'r').__enter__()
self.o = open(out_file_name, 'w').__enter__()

def __enter__(self):
return self

def __exit__(self, *exc):
self.i.__exit__(*exc)
self.o.__exit__(*exc)
< /code>

but it's both verbose and unsafe against exceptions occurring in the constructor. After searching for a while, I found this 2015 blog post, which uses contextlib.ExitStack< /code> Чтобы получить что -то очень похожее на то, что я после: < /p>

class Foo(contextlib.ExitStack):
def __init__(self, in_file_name, out_file_name):
super().__init__()
self.in_file_name = in_file_name
self.out_file_name = out_file_name

def __enter__(self):
super().__enter__()
self.i = self.enter_context(open(self.in_file_name, 'r')
self.o = self.enter_context(open(self.out_file_name, 'w')
return self
< /code>

This is pretty satisfying, but I'm perplexed by the fact that:

[list]
[*]I find nothing about this usage in the documentation, so it doesn't seem to be the "official" way to tackle this problem;
[*]in general, I find it extremely difficult to find information about this issue, which makes me think I'm trying to apply an unpythonic solution to the problem.
[/list]



[b]Some extra context[/b]: I work mostly in C++, where there is no distinction between the block-scope case and the object-scope case for this issue, as this kind of cleanup is implemented inside the destructor (think __del__
, но вызывает детерминированно), а деструктор (даже если не явно определяется) автоматически вызывает деструкторы субобъектов. Итак, оба: < /p>

Код: Выделить всё

{
std::ifstream i("in.txt");
std::ofstream o("out.txt");
// do stuff
}
< /code>

and

struct Foo {
std::ifstream i;
std::ofstream o;

Foo(const char *in_file_name, const char *out_file_name)
: i(in_file_name), o(out_file_name) {}
}

{
Foo f("in.txt", "out.txt");
}
< /code>

do all the cleanup automatically as you generally want.

I'm looking for a similar behavior in Python, but again, I'm afraid I'm just trying to apply a pattern coming from C++, and that the underlying problem has a radically different solution that I can't think of.



So, to sum it up: what is the Pythonic solution to the problem of having an object who owns objects that require cleanup become a context-manager itself, calling correctly the __enter__
/

Код: Выделить всё

__exit__
своих детей?

Подробнее здесь: https://stackoverflow.com/questions/516 ... by-a-class
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Pythonic способ сочинять контекстные менеджеры для объектов, принадлежащих классу
    Anonymous » » в форуме Python
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous
  • Контекстные менеджеры как атрибуты
    Anonymous » » в форуме Python
    0 Ответы
    19 Просмотры
    Последнее сообщение Anonymous
  • Контекстные менеджеры как атрибуты
    Anonymous » » в форуме Python
    0 Ответы
    5 Просмотры
    Последнее сообщение Anonymous
  • Контекстные менеджеры как атрибуты
    Anonymous » » в форуме Python
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • Как получить значения всех свойств (кроме наследованных), принадлежащих определенному классу в Python 3
    Anonymous » » в форуме Python
    0 Ответы
    10 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»