Почему это не работает:
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'
Почему это не работает:
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'
Измените определение X
на
class X(object):
var1 = 1
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
pass
with
присваивает возвращаемое значение метода __enter__()
имени после as
. Ваш __enter__()
вернулся None
, который был назначен z
.
Я также изменил класс на класс нового стиля (что не критично, чтобы заставить его работать).
См. docs для менеджеров контекста:
__enter__( )
Введите контекст среды выполнения и верните этот объект или другой объект, связанный с временем выполнения контекст. Значение, возвращаемое этим метод привязан к идентификатору в предложение as с операторами, использующими этот менеджер контекста. Пример контекстный менеджер, который возвращает себя файловый объект. Возврат файлов себя от__enter__()
, чтобы позволитьopen()
для использования в качестве контекста выражение в выражении a.Пример менеджера контекста, который возвращает связанный объект. возвращено
decimal.Context.get_manager()
. Эти менеджеры устанавливают активную десятичную контекст к копии оригинала десятичный контекст, а затем вернуть копия. Это позволяет сделать изменения к текущему десятичному контексту в тело заявления с без влияющий на код вне утверждение.
Ваш метод __enter__
ничего не возвращает, что совпадает с возвратом None
.
Функция, которую вы определили между "с" и "как", должна иметь и иметь только одно возвращаемое значение. 'with' передаст значение встроенному методу __enter__()
.
Объект типа класса в Python не будет возвращать никакого значения, если оно не было определено при его вызове.
Точно так же, если вы вызвали объект типа класса с его методом, который ничего не возвращает, он также выбросит исключение.
Вы не можете написать так:
with open('file.txt').readlines() as lines:
Это сгенерировало два возвращаемых значения, и это даже не позволило передать одну переменную в Python.
Но это хорошо использовать:
with open('file.txt') as f:
lines = f.readlines()