質問
というファイルを作成します 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_package
に foo
, で import 行を変更します。 foo_module.py
, エラーは出ません。ここで何が起こっているのですか?
WinXP 上で Python 2.6.4 を実行します。
解決
私はあなたがプログラムの終了時にクリーンアップに関連した2.6.4のコードにマイナーなバグをヒットしたと思います。あなたがpython -v
を実行する場合は、クリーンアップのどの時点で正確に見ることができますエラーが来ます:
# cleanup[1] foo_package.g
Exception TypeError: "'NoneType' object is not callable" in ignored
Pythonは、プログラムの終了時にクリーンアップ中にNone
への参照を設定し、それがg.shelf
の状態について混乱しているように見えます。回避策としては、g.shelf = None
後close
を設定することができます。また、私はPythonのバグトラッカーでバグを開い推薦!
他のヒント
脱毛の日後、私は最終的にatexit関数を使用して成功を収めています:
import atexit
...
cache = shelve.open(path)
atexit.register(cache.close)
これは、右の開封後は登録する最も適切なのです。複数の同時の棚を持つこの作品ます。
(明快にパイソン2.6.5)
これは確かにPythonのバグである、と私はあなたが(それを行うためのおかげで)開かれたトラッカーの問題にパッチを掲載しました。
問題は棚上げののデルの方法は、そのcloseメソッドを呼び出しているが、棚モジュールは、すでにクリーンアップを完了している場合、closeメソッドは、あなたが見るメッセージで失敗します。
あなたはg.shelf.close後「デルg.shelf」を追加することによって、あなたのコード内でメッセージを回避することができます。長いg.shelfが棚への参照のみされると、これはインタプリタのクリーンアップフェーズの前に、すぐに棚ののデルのメソッドを呼び出すことはCPythonにつながるため、エラーメッセージを回避します。
shelve
モジュールによって登録されたシャットダウン機能での例外のようです。 「無視」の部分は、シャットダウンシステムからであり、その文言は、いつかあたり特集6294 に改善される可能性があります。私はまだ...
閉じられていない1上の単純なshelve.close()
は仕事をしてくれます。
shelve.open(「somefileという」)私は、アプリケーションのランタイム全体で使用されるオブジェクトを「読み書きのための永続的な辞書」を返します。 私はアプリを終了したときに述べたように、私は「TypeError例外」例外を受け取りました。 私は私の終結配列に「近い()」の呼び出しをplased、それが問題を解決するように見えました。
例えば。 shelveObj = shelve.open( 'fileNameに') ... shelveObj.close()
OverByThere が 2018 年 7 月 17 日にコメントしました
つまり、/usr/lib/python3.5/weakref.py を開き、109 行目を次のように変更します。
def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref):
そして 117 行目は次のようになります。
_atomic_removal(d, wr.key)
他のエラーが発生するため、タブではなくスペースを使用してこれを行う必要があることに注意してください。