Pergunta

Estou tentando entender a declaração com Python. Em todos os lugares que eu olho, fala sobre abrir e fechar um arquivo, e deve substituir o bloqueio Try-Finally. Alguém poderia postar outros exemplos também. Estou apenas experimentando frasco e há com declarações em abundância. Definitivamente, solicite alguém para fornecer alguma clareza sobre isso.

Foi útil?

Solução

Há uma explicação muito boa aqui. Basicamente, a declaração com a declaração chama dois métodos especiais no objeto associado. Os métodos __enter__ e __Exit__. O método Enter retorna a variável associada à instrução "com". Enquanto o método __Exit__ é chamado após a declaração executar para lidar com qualquer limpeza (como fechar um ponteiro de arquivo).

Outras dicas

A ideia do with A declaração é fazer "fazer a coisa certa" o caminho da menor resistência. Embora o exemplo do arquivo seja o mais simples, os bloqueios de encadeamento fornecem um exemplo mais clássico de código de buggy não obviamente:

try:
    lock.acquire()
    # do stuff
finally:
    lock.release()

Este código está quebrado - se a aquisição de bloqueio falhar, a exceção errada será lançada (como o código tentará liberar uma fechadura que nunca adquiriu) ou, pior, se for uma trava recursiva, será liberada cedo. O código correto se parece com o seguinte:

lock.acquire()
try:
    # do stuff
finally:
    # If lock.acquire() fails, this *doesn't* run
    lock.release()

Usando a with Declaração, torna -se impossível errar, pois está incorporado ao gerente de contexto:

with lock: # The lock *knows* how to correctly handle acquisition and release
  # do stuff

O outro lugar onde o with A declaração ajuda muito é semelhante ao principal benefício da função e dos decoradores de classe: é preciso o código "duas peças", que pode ser separado por um número arbitrário de linhas de código (a definição de função para os decoradores, o try bloco no caso atual) e o transforma em código "One Piece", onde o programador simplesmente declara na frente o que eles estão tentando fazer.

Para exemplos curtos, isso não parece um grande ganho, mas na verdade faz uma enorme diferença ao revisar o código. Quando eu vejo lock.acquire() Em um pedaço de código, preciso rolar para baixo e verificar se há um correspondente lock.release(). Quando eu vejo with lock:, porém, essa verificação é necessária - posso ver imediatamente que o bloqueio será lançado corretamente.

Existem doze exemplos de uso with dentro PEP343, incluindo o exemplo de abertura:

  1. Um modelo para garantir que um bloqueio, adquirido no início de um bloco, seja liberado quando o bloco for deixado
  2. Um modelo para abrir um arquivo que garante que o arquivo seja fechado quando o bloco é deixado
  3. Um modelo para cometer ou reverter uma transação de banco de dados
  4. Exemplo 1 reescrito sem um gerador
  5. Redirecionar o stdout temporariamente
  6. Uma variante no aberto () que também retorna uma condição de erro
  7. Outro exemplo útil seria uma operação que bloqueia os sinais
  8. Outro uso para esse recurso é o contexto decimal
  9. Aqui está um gerente de contexto simples para o módulo decimal
  10. Um gerente de contexto genérico de "fechamento de objetos"
  11. Um contexto liberado () para liberar temporariamente um bloqueio adquirido anteriormente trocando as chamadas adquiridas () e liberação ()
  12. Um gerente de contexto "aninhado" que aninha automaticamente os contextos fornecidos da esquerda para a direita para evitar o indentação excessiva
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top