2010-02-01 47 views
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,我没有得到任何错误。 Wtf在这里?

在WinXP上运行Python 2.6.4。

回答

10

我认为你已经在程序结束2.6.4的代码清理有关的小错误。如果您运行python -v您可以在清理的哪一点看完全错误出现:

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

的Python在程序结束时,在清理过程中设置为None引用,它看起来像它变得越来越困惑的状态g.shelf。作为解决方法,您可以在close之后设置g.shelf = None。我还建议在Python的错误跟踪器中打开一个错误!

+2

解决方法的工作原理,谢谢。这里的错误报告:http://bugs.python.org/issue7835 – 2010-02-02 01:09:58

1

这似乎是由shelve模块注册的关机功能中的一个例外。 “被忽略”的部分来自关机系统,并且可能会根据Issue 6294的某个时间改进措辞。我仍然希望如何消除异常本身的答案,虽然...

2

这实际上是一个Python错误,并且我已经发布了一个补丁程序给你打开的跟踪器问题(感谢你这样做)。

问题是搁置的德尔方法调用其close方法,但如果搁置模块已经经历过清理,关闭方法失败,您看到消息。

您可以通过在g.shelf.close后面添加'del g.shelf'来避免代码中的消息。只要g.shelf是货架的唯一参考,这将导致CPython在解释器清理阶段之前立即调用搁置的方法,从而避免出现错误消息。

8

后脱发的日子里,我终于有使用的atexit函数成功:

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

它打开后立即进行登记是最合适的。这适用于多个并发货架。

在未封闭的一个(在清醒的蟒蛇2.6.5)

+5

'atexit.register(cache.close)' 不需要lambda ... – 2014-08-04 07:23:09

0

对我来说是简单的shelve.close()做的工作。

搁置。open('somefile')返回我在整个应用运行时使用的“读写的持久字典”对象。 当我终止了应用程序,我收到了类型错误异常提到。 我在终止顺序中放了一个'close()'调用,似乎解决了这个问题。

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

+0

你介意扩展答案更多的同胞程序员,以了解它如何帮助解决问题。 – Daenarys 2016-04-18 06:11:57