Pergunta

Eu crio um arquivo chamado foo_module.py contendo o seguinte código:

import shelve, whichdb, os

from foo_package.g import g

g.shelf = shelve.open("foo_path")
g.shelf.close() 

print whichdb.whichdb("foo_path")  # => dbhash
os.remove("foo_path")

Ao lado desse arquivo, crio um diretório chamado foo_package do que contém um vazio __init__.py arquivo e um arquivo chamado g.py que apenas contém:

class g:
    pass

Agora quando eu corro foo_module.py Eu recebo uma mensagem de erro estranha:

Exception TypeError: "'NoneType' object is not callable" in ignored

Mas então, se eu renomear o diretório de foo_package para foo, e mudar a linha de importação em foo_module.py, Eu não recebo nenhum erro. WTF está acontecendo aqui?

Executando o Python 2.6.4 no WinXP.

Foi útil?

Solução

Eu acho que você acertou um bug menor no código do 2.6.4 relacionado à limpeza no final do programa. Se você correr python -v Você pode ver exatamente em que ponto da limpeza o erro vem:

# cleanup[1] foo_package.g
Exception TypeError: "'NoneType' object is not callable" in  ignored

Python define referências a None durante a limpeza no final do programa, e parece que está ficando confuso sobre o status de g.shelf. Como solução alternativa, você pode definir g.shelf = None depois de close. Eu também recomendaria abrir um bug no rastreador de bugs do Python!

Outras dicas

Após dias de perda de cabelo, finalmente tive sucesso usando uma função Atexit:

  import atexit
  ...
  cache = shelve.open(path)
  atexit.register(cache.close)

É mais apropriado se registrar logo após a abertura. Isso funciona com várias prateleiras simultâneas.

(Python 2.6.5 em Lucid)

Este é realmente um bug python, e eu publiquei um patch no problema do rastreador que você abriu (obrigado por fazer isso).

O problema é que Shelve's del O método chama seu método de perto, mas se o módulo Shelve já tiver passado pela limpeza, o método de fechamento falhará com a mensagem que você vê.

Você pode evitar a mensagem em seu código adicionando 'del G.shelf' após G.shelf.close. Enquanto G. prateleira for a única referência à prateleira, isso resultará em Cpython chamando o Shelve's del Método imediatamente, antes da fase de limpeza do intérprete e, assim, evite a mensagem de erro.

Parece ser uma exceção em uma função de desligamento registrada pelo shelve módulo. A parte "ignorada" é do sistema de desligamento e pode melhorar sua redação em algum momento, por Edição 6294. Ainda estou esperando uma resposta sobre como eliminar a exceção em si, no entanto ...

para mim um simples shelve.close() em um não deslizado fez o trabalho.

Shelve.open ('SomeFile') retorna um objeto "Dicionário persistente para ler e escrever" que eu usei ao longo do tempo de execução do aplicativo. Quando encerrei o aplicativo, recebi a exceção "TypeError", conforme mencionado. Eu coloquei uma chamada 'Close ()' na minha sequência de rescisão e isso parecia resolver o problema.

por exemplo, Shelveobj = shelve.open ('nome do arquivo') ... Shelveobj.close ()

Overby, comentou em 17 de julho de 2018

Isso parece ser corrigível.

Em curta open /usr/lib/python3.5/weakref.py e altere a linha 109 para:

 def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref):

E linha 117 para:

_atomic_removal(d, wr.key)

Observe que você precisa fazer isso com espaços, não guias, pois isso causará outros erros.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top