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_packagethan 的目录,其中包含一个空__init__.py文件和一个名为的文件,该文件g.py仅包含:

class g:
    pass

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

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

但是,如果我将目录从 重命名foo_packagefoo,并将导入行更改为foo_module.py,我不会收到任何错误。Wtf在这里发生吗?

在 WinXP 上运行 Python 2.6.4。

4

6 回答 6

10

我认为您在 2.6.4 的代码中遇到了一个与程序结束时清理相关的小错误。如果您运行python -v,您可以准确地看到错误发生在什么时候:

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

PythonNone在程序结束的清理过程中设置了对 的引用,看起来它对g.shelf. 作为一种解决方法,您可以g.shelf = Noneclose. 我还建议在 Python 的错误跟踪器中打开一个错误!

于 2010-02-02T00:28:08.730 回答
10

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

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

开户后立即注册最为合适。这适用于多个并发架子。

(清醒的python 2.6.5)

于 2010-06-04T22:50:27.093 回答
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 回答
0

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)

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

于 2019-03-25T11:37:59.297 回答