Не удается распаковать некоторые данные, только что обработанные с помощью Python 3 с циклом - PullRequest
0 голосов
/ 14 февраля 2019

У меня довольно сложная структура, которую я хорошо обрабатываю, но у меня проблема с ней.

Грубо говоря, я использую объект класса Grid с ячейкой (словарь ячейки).Гусеница объекта включает в себя ячейку, а в ячейке есть список гусениц.Да, это циклично.

Травление и травление проходят нормально, пока не вставлен бит кода с меткой «Добавление этого кода вызывает проблему».

В этом случае я получаю эту ошибку:

Traceback (most recent call last):
  File "./issue.py", line 84, in <module>
    main()
  File "./issue.py", line 79, in main
    grid2 = pickle.load(handle2)
  File "./issue.py", line 25, in __hash__
    return hash(self._position)
AttributeError: 'Cell' object has no attribute '_position'

Я понимаю, что проблема связана с циклом и хэшированием, но мне нужны оба.

После просмотра проблем переполнения стека я попытался поиграть с:

object.__getstate__() 
object.__setstate__(state) 

длябез изменений.

=> Как я могу заставить свой объект мариновать / расщеплять?

Спасибо за помощь!

Я максимально упростил свой кодчтобы добраться до сути.

Ниже кода.

#!/usr/bin/env python3

import typing
import pickle

class Cell:

    def __init__(self, position: int):
        self._position = position
        self._possible_occupants = set() # type: typing.Set['Caterpillar']

    @property
    def position(self) -> int:
        return self._position

    @property
    def possible_occupants(self) -> typing.Set['Caterpillar']:
        return self._possible_occupants

    @possible_occupants.setter
    def possible_occupants(self, possible_occupants: typing.Set['Caterpillar']) -> None:
        self._possible_occupants = possible_occupants

    def __hash__(self) -> int:
        return hash(self._position)

    def __eq__(self, other: 'Cell') -> bool: #type: ignore
        return self._position == other.position

class Caterpillar:

    def __init__(self, cell: typing.Optional[Cell] = None):
        self._cells = frozenset([cell]) if cell else frozenset([])

class Grid:

    def __init__(self, file_name: str):

        self._cell_table = dict()  # type: typing.Dict[int, Cell]

        # create a cell
        cell = Cell(0)

        # put in grid
        self._cell_table[0] = cell

        # create caterpillar
        caterpillar = Caterpillar(cell)

        # put back link cell -> caterpillar
        # ADDING THIS CODE CAUSES THE PROBLEM !!!
        cell.possible_occupants.add(caterpillar)

    @property
    def cell_table(self) -> int:
        """ property """
        return self._cell_table

    def __eq__(self, other):
        return self._cell_table == other.cell_table

def main() -> None:

    input_file = 'tiny_grid.csv'
    pickle_file = input_file + ".pickle"

    grid = Grid(input_file)

    with open(pickle_file, 'wb') as handle:
        pickle.dump(grid, handle, protocol=pickle.HIGHEST_PROTOCOL)

    with open(pickle_file, 'rb') as handle2:
        grid2 = pickle.load(handle2)

    print(f"are equal : {grid2 == grid}")   

if __name__ == '__main__':
    main()

1 Ответ

0 голосов
/ 15 февраля 2019

Хорошо, мне в конце концов удалось решить эту проблему.(в любом случае, Макс)

Кажется (любой может поправить меня, если я ошибаюсь), что вы не можете выбрать (фактически удалить) объект - или объект, содержащий объект - с пользовательской хэш-функцией (из этого опыта)

Объект был в наборе, поэтому нужно было иметь хеш.Тем не менее, я определил экв для объекта.Кажется, eq рассеивает нативный хеш, поэтому мне пришлось поставить свой собственный хеш, так что ... я не смог засолить ... и опубликовал здесь.

Я решил проблему, удалив eq и хеш , поэтому равенство было тождеством (адресом) и изменило код, чтобы позаботиться об этом (путем явной проверки равенства по значению)

Примечаниеэто определение равенства не только заставляет определять хеш (с неудобствами ниже), но также снижает производительность путем введения нового слоя.

Кстати, моя настоящая проблема была не в консервировании, а в многопроцессорности.Так как у меня был пул рабочих, многопроцессорная библиотека, кажется, перебирает мои данные, чтобы передать их другим (или, скорее всего, обратно).Я представил здесь проблему травления, чтобы уменьшить проблему.

Извлеченный урок: не хэшируйте, если вы мариноваете !!!

(Небольшое примечание: делаетхороший каламбур по-французски, так как "хэш" звучит как наркотики, а "маринованные" звучит как алкоголь)

...