Понимание цели возврата себя в классе менеджера контекста

Попытка понять, как диспетчеры контекста работают для перехвата ошибок, а точнее роль метода __enter__() в классе, созданном для использования в качестве диспетчера контекста, как он работает здесь в процессе «отлова ошибок» и почему self это все, что возвращается в методе __enter__().

Учитывая следующее использование диспетчера контекста для обнаружения ошибки:

import unittest
class InvoiceCalculatorTests(unittest.TestCase):
    def test_no_pay(self):
        with self.assertRaises(ValueError):
            pay = divide_pay(0, {"Alice": 3.0, "Bob": 3.0, "Carol": 6.0})

Вот то, что я считаю исходным кодом для assertRaises:

class _AssertRaisesContext(_AssertRaisesBaseContext):
    """A context manager used to implement TestCase.assertRaises* methods."""

    _base_type = BaseException
    _base_type_str = 'an exception type or tuple of exception types'

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, tb):
        if exc_type is None:
            try:
                exc_name = self.expected.__name__
            except AttributeError:
                exc_name = str(self.expected)
            if self.obj_name:
                self._raiseFailure("{} not raised by {}".format(exc_name,
                                                                self.obj_name))
            else:
                self._raiseFailure("{} not raised".format(exc_name))
        else:
            traceback.clear_frames(tb)
        if not issubclass(exc_type, self.expected):
            # let unexpected exceptions pass through
            return False
        # store exception, without traceback, for later retrieval
        self.exception = exc_value.with_traceback(None)
        if self.expected_regex is None:
            return True

        expected_regex = self.expected_regex
        if not expected_regex.search(str(exc_value)):
            self._raiseFailure('"{}" does not match "{}"'.format(
                     expected_regex.pattern, str(exc_value)))
        return True

Я попытался просмотреть PEP-0343, чтобы получить некоторое представление, но это немного за пределами моих текущих знаний/понимания, чтобы понять, что там содержится. Может ли кто-нибудь объяснить, с точки зрения относительного непрофессионала, роль __enter__() и __exit__() в процессе «поймать» ValueError здесь и почему __enter__() просто возвращает себя?


person AdjunctProfessorFalcon    schedule 18.12.2015    source источник


Ответы (1)


__enter__() предназначен для настройки. Этот конкретный контекстный менеджер не требует настройки. Так что все, что ему нужно сделать, это вернуть объект, который будет указан в предложении as, который является просто самим собой.

person Chad S.    schedule 18.12.2015