shelve(python)的一个非常奇怪的问题

shelve(python)的一个非常奇怪的问题,python,shelve,Python,Shelve,我创建了一个名为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\u package的目录,其

我创建了一个名为
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\u package
的目录,其中包含一个空的
\uuuu init\uuuuuuuuuuuupy
文件和一个名为
g.py
的文件,其中只包含:

class g:
    pass
现在,当我运行
foo_module.py
时,我收到一条奇怪的错误消息:

异常类型错误:“'NoneType'对象不可调用”处于忽略状态

但是,如果我将目录从
foo_package
重命名为
foo
,并更改
foo_module.py
中的导入行,我不会得到任何错误。世跆联在这里进行什么


在WinXP上运行Python 2.6.4。

这似乎是由
shelve
模块注册的关闭函数中的一个异常。“忽略”部分来自关闭系统,可能会在某个时候得到改进。我仍然希望得到一个关于如何消除异常本身的答案,不过…

我认为您在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
。我还建议在Python的bug跟踪器中打开一个bug

这确实是一个Python错误,我已经发布了一个补丁给您打开的跟踪器问题(感谢您这么做)

问题是shelve的del方法调用它的close方法,但是如果shelve模块已经完成了清理,close方法将失败,并显示您看到的消息


您可以通过在g.shelf.close之后添加“del g.shelf”来避免代码中的消息。只要g.shelf是对shelf的唯一引用,这将导致CPython在解释器清理阶段之前立即调用shelve的del方法,从而避免错误消息。

经过几天的脱发,我终于成功地使用了atexit函数:

  import atexit
  ...
  cache = shelve.open(path)
  atexit.register(cache.close)
开封后立即注册是最合适的。这适用于多个并发工具架


(lucid上的python 2.6.5)

对于我来说,一个简单的
shelve.close()
在一个未关闭的文件上完成了这项工作

open('somefile')返回我在整个应用程序运行时使用的“用于读写的持久字典”对象。 当我终止应用程序时,我收到了前面提到的“TypeError”异常。 我在终止序列中调用了“close()”,这似乎解决了问题

e、 g。 shelveObj=shelve.open('文件名') ... shelveObj.close()

在简短的open/usr/lib/python3.5/weakref.py中,将第109行更改为:

 def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref):
第117行至:

_atomic_removal(d, wr.key)

注意,您需要使用空格而不是制表符来执行此操作,因为这会导致其他错误。

此解决方法有效,谢谢。下面是错误报告:您是否介意为其他程序员进一步扩展答案,以了解它如何帮助解决问题。
2.7.15rc1(默认值,2018年4月15日,21:51:34)
,问题仍然存在;这个(而且只有这个)解决方案有效