5

foo_module.py次のコードを含むというファイルを作成します。

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

foo_packageそのファイルの隣に、空__init__.pyのファイルと、次のg.pyものだけを含むという名前のファイルを含むという名前のディレクトリを作成します。

class g:
    pass

実行するfoo_module.pyと、奇妙なエラーメッセージが表示されます。

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

しかし、ディレクトリの名前を からfoo_packagefoo変更し、インポート行を に変更してfoo_module.pyも、エラーは発生しません。ここで何が起こっているのですか?

WinXP で Python 2.6.4 を実行しています。

4

6 に答える 6

10

数日間の脱毛の後、私はついにatexit関数を使用して成功しました:

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

開封後すぐに登録するのが最適です。これは、複数の同時シェルフで機能します。

(明快なPython 2.6.5)

于 2010-06-04T22:50:27.093 に答える
10

プログラムの最後のクリーンアップに関連する 2.6.4 のコードで小さなバグに遭遇したと思います。実行python -vすると、クリーンアップのどの時点でエラーが発生したかを正確に確認できます。

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

Python はNone、プログラムの最後のクリーンアップ中に への参照を設定し、 のステータスについて混乱しているようですg.shelfg.shelf = None回避策として、 の後に設定できますclose。また、Python のバグ トラッカーでバグを開くこともお勧めします。

于 2010-02-02T00:28:08.730 に答える
2

これは確かに Python のバグです。あなたがオープンしたトラッカーの問題にパッチを投稿しました (ありがとうございます)。

問題は、shelve のdelメソッドがその close メソッドを呼び出すことですが、shelve モジュールが既にクリーンアップされている場合、close メソッドは失敗し、表示されるメッセージが表示されます。

g.shelf.close の後に「del g.shelf」を追加することで、コード内のメッセージを回避できます。g.shelf がシェルフへの唯一の参照である限り、インタープリターのクリーンアップ フェーズの前に CPython がすぐにシェルフのdelメソッドを呼び出すことになり、エラー メッセージが回避されます。

于 2010-02-02T03:00:26.213 に答える
1

shelveモジュールが登録したシャットダウン機能の例外のようです。「無視された」部分はシャットダウン システムからのものであり、Issue 6294 に従って、いつかその文言が改善される可能性があります。ただし、例外自体を排除する方法についての回答をまだ望んでいます...

于 2010-02-02T00:22:07.000 に答える
1

私にとっては、閉じられていない単純なshelve.close()ものが仕事をしました。

shelve.open('somefile') は、アプリのランタイム全体で使用した「読み取りと書き込みのための永続的な辞書」オブジェクトを返します。アプリを終了すると、前述の「TypeError」例外を受け取りました。終了シーケンスで「close()」呼び出しを実行したところ、問題が解決したようです。

例: shelveObj = shelve.open('fileName') ... shelveObj.close()

于 2016-04-18T05:50:54.197 に答える