У меня довольно сложная структура, которую я хорошо обрабатываю, но у меня проблема с ней.
Грубо говоря, я использую объект класса 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()