Domanda

I creare un file chiamato foo_module.py che contiene il seguente codice:

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")

Accanto a quel file creo una directory chiamata foo_package che contiene un file __init__.py vuoto e un file chiamato g.py che contiene solo:

class g:
    pass

Ora, quando corro foo_module.py ricevo un messaggio di errore strano:

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

Ma allora, se mi rinominare la directory da foo_package a foo, e cambiare la linea di importazione in foo_module.py, non ottengo alcun errore. Wtf sta succedendo qui?

L'esecuzione Python 2.6.4 su WinXP.

È stato utile?

Soluzione

Credo che hai raggiunto un bug minore nel codice 2.6.4 del relativo alla pulizia alla fine del programma. Se si esegue python -v potete vedere esattamente a che punto della pulizia l'errore viene:

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

Python imposta riferimenti al None durante la pulizia alla fine del programma e sembra che la cosa si fa confuso sullo stato della g.shelf. Per aggirare il problema è possibile impostare g.shelf = None dopo la close. Auspico inoltre l'apertura di un bug nel bug tracker di Python!

Altri suggerimenti

Dopo giorni di perdita di capelli, ho finalmente avuto successo utilizzando una funzione atexit:

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

E 'più appropriato per registrare subito dopo l'apertura. Questo funziona con più scaffali simultanei.

(Python 2.6.5 su lucido)

Questo è davvero un bug Python, e ho pubblicato una patch per il problema Tracker è stato aperto (grazie per farlo).

Il problema è che di accantonare del metodo chiama il suo metodo close, ma se il modulo ripiano è già stato attraverso la pulizia, il metodo close riesce con il messaggio che si vede.

È possibile evitare il messaggio nel codice con l'aggiunta di 'del g.shelf' dopo g.shelf.close. Finché g.shelf è l'unico riferimento allo scaffale, questo si tradurrà in CPython chiamando il ripiano del del Metodo subito, prima che la fase di pulitura interprete, e quindi evitare il messaggio di errore.

Sembra essere un'eccezione in una funzione di arresto registrato dal modulo shelve. La parte "ignorato" è dal sistema di spegnimento, e potrebbe ottenere la sua formulazione migliorata qualche volta, per Edizione 6294 . Sto ancora sperando in una risposta su come eliminare l'eccezione stessa, anche se ...

per me una semplice shelve.close() su un uno non chiusa ha fatto il lavoro.

shelve.open ( 'somefile') restituisce un "dizionario persistente per la lettura e la scrittura di" oggetto che ho usato durante il runtime del app. quando ho interrotto l'app che ho ricevuto l'eccezione "TypeError", come menzionato. Ho plased una 'stretta) (' chiamata nella mia sequenza di terminazione e che sembrava per risolvere il problema.

es. shelveObj = shelve.open ( 'filename') ... shelveObj.close ()

OverByThere commentato 17 luglio 2018

Questo sembra essere risolvibile.

In breve aperto /usr/lib/python3.5/weakref.py e cambiare la linea 109 a:

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

E la linea 117 a:

_atomic_removal(d, wr.key)

Si noti che dovete fare questo con spazi, non schede come questo causerà altri errori.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top