Объект становится None при использовании менеджера контекста - PullRequest
11 голосов
/ 23 февраля 2011

Почему это не работает:

class X:
    var1 = 1
    def __enter__(self): pass
    def __exit__(self, type, value, traceback): pass

with X() as z:
    print z.var1

Я получаю:

print z.var1
AttributeError: 'NoneType' object has no attribute 'var1'

Ответы [ 2 ]

22 голосов
/ 23 февраля 2011

Измените определение X на

class X(object):
    var1 = 1
    def __enter__(self):
        return self
    def __exit__(self, type, value, traceback):
        pass

with присваивает возвращаемое значение метода __enter__() имени после as.Ваш __enter__() вернул None, который был назначен на z.

Я также изменил класс на класс нового стиля (что не критично для его работы).

4 голосов
/ 23 февраля 2011

См. документы для менеджеров контекста:

__enter__( ) Введите контекст выполнения и верните либо этот объект, либо другой объект, связанный с контекстом выполнения.Значение, возвращаемое этим методом, привязывается к идентификатору в предложении as с инструкциями, использующими этот менеджер контекста.Примером менеджера контекста, который возвращает себя, является объект файла.Файловые объекты возвращают себя из __enter__(), чтобы разрешить использование open() в качестве выражения контекста в операторе with.

Примером диспетчера контекста, который возвращает связанный объект, является тот, который возвращается decimal.Context.get_manager(),Эти менеджеры устанавливают активный десятичный контекст на копию исходного десятичного контекста и затем возвращают копию.Это позволяет вносить изменения в текущий десятичный контекст в теле оператора with, не затрагивая код вне оператора with.

Ваш метод __enter__ ничего не возвращает, что то же самоекак возвращение None.

...