2010-02-01 53 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