15 октября 2008

Контекст-менеджер и with в Python 2.6

Релиз Python 2.6, состоявшийся 1 октября, как-то прошел мимо меня. Поэтому, чтобы восполнить обнаружившийся пробел, я его скачал и установил. Первой пробой новой версии интерпретатора стала попытка написать контекст-менеджер и попробовать его с оператором with.

  1. from __future__ import print_function
  2. from random import random
  3. class Box:
  4. def __init__(self, i):
  5. print ("Construct Box")
  6. self.__I = i
  7. def getI(self):
  8. if random() > .5:
  9. return self.__I
  10. else:
  11. raise
  12. def setI(self, i):
  13. self.__I = i
  14. def __enter__(self):
  15. print ("Enter in Box, I = ", self.__I)
  16. return self
  17. def __exit__(self, type, value, tb):
  18. if tb is None:
  19. print ("All right, I = ", self.__I)
  20. else:
  21. print ("Aaaaa!!!")
  22. return True #Если не поставить, исключение пойдет выше
  23. with Box(3) as a:
  24. print (a.getI())


В случае нормального исхода, результат будет следующий:

Construct Box
Enter in Box, I = 3
3
All right, I = 3

Т.е., сначала вызывается конструктор, затем __enter__(), далее, собственно, выполняется код внутри блока with, а потом — __exit__(). В случае ошибки, получаем следующее:

Construct Box
Enter in Box, I = 3
Aaaaa!!!

Причем, если опустить строку return True, получим необработаное исключение:
Traceback (most recent call last):
File "C:/Python26/1", line 26, in
print (a.getI())
Empty

Комментариев нет: