无法解开一些仅用python 3腌制的数据

时间:2019-02-13 21:01:12

标签: hash python-3.6 pickle cycle attributeerror

我有一个非常复杂的结构,可以腌制得很好,但在腌制时遇到问题。

粗略地讲,我腌制一个Grid类的对象,该对象具有一个Cell(单元格的字典)。对象毛毛虫包括一个单元格,并且一个单元格具有一个毛毛虫列表。是的,它会循环。

酸洗和酸洗都可以进行,直到插入标记为“添加此代码引起的问题”的代码为止。

在这种情况下,我会收到此错误:

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 :(得分:0)

好的,我最终设法解决了这个问题。 (仍然感谢Maks)

(如果我做错了,任何人都可以纠正我)您不能(实际上不挑剔)腌制(具有这种经验)具有用户定义的哈希函数的对象-或包含对象的对象

该对象位于集合中,因此需要具有哈希值。但是,我已经为对象定义了 eq 。似乎 eq 消除了本机哈希,所以我不得不放入自己的哈希,所以...我无法腌制...此处发布的答案。

我通过删除 eq hash 来解决了这个问题,因此等式就是身份(地址),并更改了代码以解决该问题(通过显式测试价值平等)

请注意,定义相等性不仅会强制定义哈希(以下不便之处),而且还会通过引入新层来降低性能。

顺便说一句,我真正的问题不是关于酸洗,而是关于多处理。由于我有很多工人,因此多处理库似乎会对我的数据进行腌制以将其传递给其他人(或者更可能返回)。我在这里提交了酸洗问题以减少问题。

经验教训:如果您泡菜,不要散列!!!

(小注:由于“哈希”听起来像是毒品,而“刺痛”听起来像是喝酒,所以法语中的双关语很不错)