Действительно странная проблема с полкой (python)

StackOverflow https://stackoverflow.com/questions/2180946

  •  24-09-2019
  •  | 
  •  

Вопрос

Я создаю файл с именем 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)

Обратите внимание, что вам нужно сделать это с пробелами, а не вкладками, так как это приведет к другим ошибкам.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top