Eu vi isso no código de alguém. O que isso significa?
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
fonte
fonte
Respostas:
O uso desses métodos mágicos (
__enter__
,__exit__
) permite implementar objetos que podem ser usados facilmente com awith
instruçãoA idéia é que facilita a criação de código que precisa de algum código 'cleandown' executado (pense nele como um
try-finally
bloco). Mais algumas explicações aqui .Um exemplo útil pode ser um objeto de conexão com o banco de dados (que fecha automaticamente a conexão assim que a instrução 'with' correspondente estiver fora do escopo):
Como explicado acima, use esse objeto com a
with
instrução (pode ser necessário fazerfrom __future__ import with_statement
na parte superior do arquivo se você estiver no Python 2.5).PEP343 - A declaração 'with' também possui uma boa redação.
fonte
__enter__
deve retornarself
sempre, pois somente outros métodos da classe podem ser chamados no contexto.def __enter__(self)
no PEP 343 e ninguém o fazreturn self
: python.org/dev/peps/pep-0343 . Porque você acha isso?self
objeto, conforme explicado aqui: stackoverflow.com/questions/38281853/… 2) self.XYZ é apenas parte do auto-objeto e retornando o identificador apenas para o que me parece inadequado do ponto de vista da manutenção. Eu preferiria preferem voltar alça para completa objeto e, em seguida, fornecer APIs públicas para apenas os componentesself
objeto, o que eu quero expor para o usuário como emwith open(abc.txt, 'r') as fin: content = fin.read()
self
a partir__enter__
, que é como é que você pode processar o arquivo comof
dentrowith open(...) as f
Se você sabe o que são gerenciadores de contexto , não precisa mais nada para entender
__enter__
e__exit__
métodos mágicos. Vamos ver um exemplo muito simples.Neste exemplo, estou abrindo myfile.txt com a ajuda da função open . O bloco try / finally garante que, mesmo que ocorra uma exceção inesperada, myfile.txt seja fechado.
Agora estou abrindo o mesmo arquivo com a declaração:
Se você olhar o código, não fechei o arquivo e não há bloco try / finalmente . Porque com a instrução fecha automaticamente myfile.txt . Você pode até checar chamando
print(fp.closed)
atributo - que retornaTrue
.Isso ocorre porque os objetos de arquivo (fp no meu exemplo) retornados pela função open possuem dois métodos internos
__enter__
e__exit__
. Também é conhecido como gerenciador de contexto.__enter__
O método é chamado no início de with block e o__exit__
método é chamado no final. Nota: with statement funciona apenas com objetos que suportam o protocolo de gerenciamento de contexto, ou seja, eles têm__enter__
e__exit__
métodos. Uma classe que implementa os dois métodos é conhecida como classe de gerenciador de contexto.Agora vamos definir nossa própria classe de gerenciador de contexto .
Espero que agora você tenha uma compreensão básica dos métodos
__enter__
e dos__exit__
métodos mágicos.fonte
Achei estranhamente difícil localizar os documentos
__enter__
e__exit__
métodos python no Google , para ajudar outras pessoas aqui no link:https://docs.python.org/2/reference/datamodel.html#with-statement-context-managers
https://docs.python.org/3/reference/datamodel.html#with-statement-context-managers
(o detalhe é o mesmo para as duas versões)
Eu esperava uma descrição clara dos
__exit__
argumentos do método. Isso está faltando, mas podemos deduzi-los ...Presumivelmente,
exc_type
é a classe da exceção.Ele diz que você não deve aumentar novamente a exceção transmitida. Isso nos sugere que um dos argumentos pode ser uma instância de exceção real ... ou talvez você deva instanciar você mesmo a partir do tipo e valor?
Podemos responder consultando este artigo:
http://effbot.org/zone/python-with-statement.htm
... é tão claramente
value
uma instância de exceção.E presumivelmente
traceback
é um objeto de rastreamento de Python .fonte
Além das respostas acima para exemplificar a ordem de chamada, um exemplo simples de execução
Produz a saída:
Um lembrete: ao usar a sintaxe
with myclass() as mc
, a variável mc obtém o valor retornado por__enter__()
, no caso acimaNone
! Para esse uso, é necessário definir o valor de retorno, como:fonte
tente adicionar minhas respostas (meu pensamento de aprender):
__enter__
e[__exit__]
ambos são métodos que são chamados na entrada e saída do corpo da " declaração with " ( PEP 343 ) e a implementação de ambos é chamada de gerenciador de contexto.a instrução with pretende ocultar o controle de fluxo da cláusula try finally e tornar o código inescrutável.
a sintaxe da instrução with é:
traduzidos para (como mencionado no PEP 343):
tente algum código:
e agora tente manualmente (a seguir, sintaxe de conversão):
o resultado do lado do servidor é o mesmo de antes
desculpe pelo meu inglês ruim e minhas explicações pouco claras, obrigado ....
fonte
Isso é chamado de gerenciador de contexto e eu só quero acrescentar que abordagens semelhantes existem para outras linguagens de programação. Compará-los pode ser útil para entender o gerenciador de contexto em python. Basicamente, um gerenciador de contexto é usado quando estamos lidando com alguns recursos (arquivo, rede, banco de dados) que precisam ser inicializados e, em algum momento, derrubados (descartados). No Java 7 e acima, temos o gerenciamento automático de recursos que assume a forma de:
Observe que a sessão precisa implementar
AutoClosable
ou uma de suas (muitas) subinterfaces.Em C # , usamos instruções para gerenciar recursos que assumem a forma de:
Em que
Session
deve implementarIDisposable
.Em python , a classe que usamos deve implementar
__enter__
e__exit__
. Portanto, assume a forma de:E, como outros apontaram, você sempre pode usar a instrução try / finally em todos os idiomas para implementar o mesmo mecanismo. Isso é apenas açúcar sintático.
fonte