Я нахожусь на среднем уровне с Python, и недавно я играл с менеджерами контекста Python. Я хотел инвертировать порядок, в котором выполняются вход и выход. Итак, я написал этот менеджер контекста:
class ReversibleContextManager(object):
def __enter__(self, *args):
print('d')
return self
def __exit__(self, *args):
print('g')
return self
def __invert__(self):
self.__enter__, self.__exit__ = self.__exit__, self.__enter__
return self
Он отлично работает вперед:
with ContextManager():
print('o')
d
o
g
Но в обратном порядке мы все равно получаем:
with ~ContextManager():
print('a')
d
o
g
Если мы вызовем функции входа и выхода явно, как и ожидалось, мы получим:
with ReversibleContextManager() as c:
c.__enter__()
print('o')
c.__exit__()
d
d
o
g
g
НО порядок ОБРАЩАЕТСЯ для метода экземпляра!
with ~ReversibleContextManager() as c:
c.__enter__()
print('o')
c.__exit__()
d
g
o
d
g
Таким образом, похоже, что вызовы оператора with используют метод, привязанный к классу, а не к экземпляру (правильная ли это терминология?). Ожидается ли это?
i.e.
то, что называется:
c = ReversibleContextManager()
c.__invert__()
ReversibleContextManager.__enter__(c)
...in context...
ReversibleContextManager.__exit__(c)
Вместо того, что я ожидаю:
c = ReversibleContextManager()
c.__invert__()
c.__enter__()
...in context...
c.__exit__()