Пожалуйста, приведите пример кода

аюсь засолитьnamedtuple:

from collections import namedtuple
import cPickle

class Foo:

    Bar = namedtuple('Bar', ['x', 'y'])

    def baz(self):
        s = set()
        s.add(Foo.Bar(x=2, y=3))
        print cPickle.dumps(s)

if __name__ == '__main__':
    f = Foo()
    f.baz()

Это дает следующий вывод:

Traceback (most recent call last):
  File "scratch.py", line 15, in <module>
    f.baz()
  File "scratch.py", line 11, in baz
    print cPickle.dumps(s)
cPickle.PicklingError: Can't pickle <class '__main__.Bar'>: attribute lookup __main__.Bar failed

Что я делаю неправильно? Проблема в том, чтоBar является членомFoo? (Перемещение определенияBar на верхнем уровне решает проблему, хотя мне все равно любопытно, почему это происходит.)

 frank23 сент. 2018 г., 18:42
Является ли ответ @DaveButler правильным? Кто-нибудь может подтвердить или опровергнуть?
 Dave Butler31 мар. 2015 г., 15:49
Использование python3 и протокола pickle 4 исправляет это

Ответы на вопрос(2)

так как он использует путь к объекту внутри приложения, чтобы восстановить его позже.

Непосредственное решение состоит в том, чтобы не вкладывать классы, т.е.Bar определение снаружиFoo, Код все равно будет работать.

Но лучше сделатьне использовать pickle вообще хранить данные. Используйте другой формат сериализации, напримерjsonили база данных, какsqlite3.

Вы только что столкнулись с одним из множества неудобств Pickle: если вы измените свой код, переместите вещи или иногда внесете небольшие структурные изменения, ваши данные станут недоступными для загрузки.

Помимо этого, у pickle есть и другие недостатки: он медленный, небезопасный, только для Python ...

Решение Вопроса

Да, проблема в том, что это член класса:

>>> class Foo():
...     Bar = namedtuple('Bar', ['x','y'])
...     def baz(self):
...         b = Foo.Bar(x=2, y=3)
...         print(type(b))
...
>>> a = Foo()
>>> a.baz()
<class '__main__.Bar'>

Проблема в том, что когдаnamedtuple() возвращает объект типа, он не знает о том факте, что он присваивается члену класса - и, таким образом, он сообщает объекту типа, что его имя типа должно быть__main__.Barхотя это действительно должно быть__main__.Foo.Bar.

 So S18 апр. 2017 г., 15:41
Как я мог использоватьGetState? Я не знаю, как это реализовать. В данный момент я работаю с временным решением, которое переносит список именованных кортежей в словарь.
 Amber13 янв. 2011 г., 06:25
namedtuple просто не очень хорошо играет с классами. Вы могли бы написать__getstate__ для объекта, который позаботится об этом вручную.
 Nick Heiner13 янв. 2011 г., 06:24
Итак ... есть какой-то обходной путь, или это просто запрещено?
 Amber13 янв. 2011 г., 06:27
 motoku05 июн. 2011 г., 04:58
Будет ли раннее связывание захватить это?

Ваш ответ на вопрос