Действительно странная проблема с полкой (python)
Вопрос
Я создаю файл с именем 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
, и измените строку импорта в foo_module.py
, я не получаю никаких ошибок.Что здесь происходит?
Запуск Python 2.6.4 на WinXP.
Решение
Я думаю, вы обнаружили небольшую ошибку в коде версии 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)
Это наиболее подходит для регистрации сразу после открытия. Это работает с несколькими параллельными полками.
(Python 2.6.5 на ясно)
Это действительно ошибка Python, и я опубликовал патч к проблеме трекера, который вы открыли (спасибо за это).
Проблема в том, что полки дель Метод вызывает свой метод закрытия, но если модуль SHELVE уже прошел через очистку, метод закрытия не удается с сообщением, которое вы видите.
Вы можете избежать сообщения в вашем коде, добавив «del g.) После g.shelf.close. Пока G.shelf - единственная ссылка на полку, это приведет к CPYFON, вызывая полки дель Способ сразу перед фазой очистки переводчика и, таким образом, избегать сообщения об ошибке.
Кажется, это исключение в функции отключения, зарегистрированной shelve
модуль. Часть «игнорируемой» находится из системы отключения, и может получить его формулировку, улучшенную когда-нибудь, за Выпуск 6294.. Отказ Я все еще надеюсь на ответ на то, как устранить само собой исключение, хотя ...
Для меня простой shelve.close()
на неразмещенном сделал работу.
Shelve.Open («quotefile») Возвращает «постоянный словарь для чтения и записи», который я использовал во время выполнения приложения. Когда я прекратил приложение, я получил исключение «Типеррера», как упоминалось. Я отметил «закрыть ()» вызов в моей последовательности терминации, и это, казалось, это решило проблему.
Например, Shelveobj = Shelve.Open («имя файла») ... ShelveObj.close ()
AveryThere прокомментировал 17 июля 2018 года
В коротким открытии /usr/lib/python3.5/weakref.py и измените строку 109 к:
def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref):
И строка 117 к:
_atomic_removal(d, wr.key)
Обратите внимание, что вам нужно сделать это с пробелами, а не вкладками, так как это приведет к другим ошибкам.