Я видел это в чьем-то коде. Что это значит?
def __enter__(self):
return self
def __exit__(self, type, value, tb):
self.stream.close()
from __future__ import with_statement#for python2.5
class a(object):
def __enter__(self):
print 'sss'
return 'sss111'
def __exit__(self ,type, value, traceback):
print 'ok'
return False
with a() as s:
print s
print s
python
oop
with-statement
zjm1126
источник
источник
Ответы:
Использование этих магических методов (
__enter__
,__exit__
) позволяет вам реализовать объекты, которые можно легко использовать сwith
оператором.Идея состоит в том, что он облегчает создание кода, который требует выполнения некоторого кода очистки (думайте о нем как о
try-finally
блоке). Еще несколько объяснений здесь .Полезным примером может быть объект соединения с базой данных (который затем автоматически закрывает соединение, как только соответствующий оператор with выходит из области видимости):
Как объяснено выше, используйте этот объект с
with
оператором (вам может потребоваться сделатьfrom __future__ import with_statement
это вверху файла, если вы используете Python 2.5).PEP343 - У оператора with тоже хорошая запись.
источник
__enter__
должен возвращатьсяself
всегда, так как тогда только другие методы класса могут быть вызваны в контексте.def __enter__(self)
PEP 343 есть 4 примера, но никто этого не делаетreturn self
: python.org/dev/peps/pep-0343 . Почему ты так думаешь?self
объекта, как описано здесь: stackoverflow.com/questions/38281853/… 2) self.XYZ является лишь частью объекта self и возвращать ручку только к тому, что кажется мне неуместным с точки зрения обслуживания. Я бы предпочел вернуть дескриптор для завершения объекта, а затем предоставить открытые API-интерфейсы только для тех компонентов компонентовself
, которые я хочу предоставить пользователю, как вwith open(abc.txt, 'r') as fin: content = fin.read()
self
из__enter__
, который как же вы можете обработать этот файл какf
внутриwith open(...) as f
Если вы знаете, что такое контекстные менеджеры , вам больше ничего не нужно понимать
__enter__
и использовать__exit__
магические методы. Давайте посмотрим на очень простой пример.В этом примере я открываю myfile.txt с помощью функции open . Блок try / finally гарантирует, что даже в случае непредвиденного исключения myfile.txt будет закрыт.
Теперь я открываю тот же файл с заявлением:
Если вы посмотрите на код, я не закрыл файл и нет блока try / finally . Потому что с оператором автоматически закрывается myfile.txt . Вы даже можете проверить это, вызвав
print(fp.closed)
атрибут - который возвращаетTrue
.Это потому, что файловые объекты (fp в моем примере), возвращаемые функцией open, имеют два встроенных метода
__enter__
и__exit__
. Он также известен как менеджер контекста.__enter__
метод вызывается в начале с блока и__exit__
метод вызывается в конце. Замечания: оператор with работает только с объектами, которые поддерживают протокол управления контекстами, т. Е. Имеют методы__enter__
и__exit__
методы. Класс, который реализует оба метода, известен как класс менеджера контекста.Теперь давайте определим нашу собственную класс менеджера контекста .
Я надеюсь, что теперь у вас есть базовое понимание обоих
__enter__
и__exit__
магических методов.источник
Мне было странно трудно найти документы
__enter__
и__exit__
методы Python для Googling, поэтому, чтобы помочь другим, вот ссылка:https://docs.python.org/2/reference/datamodel.html#with-statement-context-managers
https://docs.python.org/3/reference/datamodel.html#with-statement-context-managers
(детали одинаковы для обеих версий)
Я надеялся на четкое описание
__exit__
аргументов метода. Этого не хватает, но мы можем вывести их ...Предположительно
exc_type
это класс исключения.В нем говорится, что вы не должны повторно поднимать переданное исключение. Это говорит нам о том, что один из аргументов может быть фактическим экземпляром Exception ... или, может быть, вы должны создать его экземпляр самостоятельно по типу и значению?
Мы можем ответить, посмотрев эту статью:
http://effbot.org/zone/python-with-statement.htm
... так ясно
value
, это исключение.И предположительно
traceback
это объект трассировки Python .источник
В дополнение к приведенным выше ответам, чтобы проиллюстрировать порядок вызова, простой пример запуска
Производит вывод:
Напоминание: при использовании синтаксиса
with myclass() as mc
переменная mc получает значение, возвращаемое__enter__()
, в вышеприведенном случаеNone
! Для такого использования необходимо определить возвращаемое значение, например:источник
попробуйте добавить мои ответы (моя мысль об обучении):
__enter__
и[__exit__]
оба являются методами, которые вызываются при входе и выходе из тела « оператора with » ( PEP 343 ), и реализация обоих называется контекстным менеджером.Оператор with предназначен для сокрытия управления потоком предложения try finally и делает код непостижимым.
синтаксис оператора with:
что переводится как (как упомянуто в PEP 343):
попробуйте немного кода:
и теперь попробуйте вручную (следуя синтаксису перевода):
результат на стороне сервера такой же, как и раньше
извините за мой плохой английский и мои неясные объяснения, спасибо ....
источник
Это называется диспетчер контекста, и я просто хочу добавить, что аналогичные подходы существуют для других языков программирования. Сравнение их может помочь понять менеджер контекста в python. По сути, менеджер контекста используется, когда мы имеем дело с некоторыми ресурсами (файл, сеть, база данных), которые необходимо инициализировать и в какой-то момент свернуть (утилизировать). В Java 7 и выше у нас есть автоматическое управление ресурсами, которое принимает форму:
Обратите внимание, что Session необходимо реализовать
AutoClosable
или один из его (многих) подчиненных интерфейсов.В C # мы используем операторы для управления ресурсами, которые принимают форму:
В котором
Session
следует реализоватьIDisposable
.В python класс, который мы используем, должен реализовывать
__enter__
и__exit__
. Так что он принимает форму:И, как отмечали другие, вы всегда можете использовать оператор try / finally на всех языках для реализации одного и того же механизма. Это просто синтаксический сахар.
источник