hash - 无法用循环解开一些刚刚用 python 3 腌制的数据
问题描述
我有一个相当复杂的结构,我腌制得很好,但解封有问题。
粗略地说,我腌制了一个 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()
解决方案
好的,我最终设法解决了这个问题。(无论如何感谢Maks)
似乎(如果我错了,任何人都可以纠正我)你不能腌制(实际上是取消腌制)一个对象 - 或包含一个对象的对象 - 具有用户定义的哈希函数(来自这个经验)
该对象在一个集合中,因此需要有一个散列。但是,我已经为该对象定义了一个eq 。似乎eq消除了本机哈希,所以我不得不放我自己的哈希,所以......我不能腌制......ans张贴在这里。
我通过删除eq和哈希解决了这个问题,所以相等是身份(地址)并更改了代码来处理这个问题(通过按值显式测试相等)
请注意,定义相等性不仅会强制定义哈希(以下带来不便),还会通过引入新层来降低性能。
顺便说一句,我真正的问题不是酸洗,而是多处理。由于我有一群工人,多处理库似乎会腌制我的数据以将它们传递给其他人(或者更有可能返回)。我在这里提交了酸洗问题以减少问题。
经验教训:如果你腌制,不要散列!
(小旁注:在法语中是一个很好的双关语,因为“hash”听起来像毒品,而“pickle”听起来像喝酒)
推荐阅读
- c++ - 使用 Direct2D 在非客户区绘图
- google-drive-api - 如何获取个人资料信息谷歌照片库api
- python - ValueError:形状不匹配:形状相同
- sorting - 通过 Google 表格中的参数对海量数据进行排序
- xml - 需要通过 XSLT 将我的 XML 转换为另一个特定格式的 XML
- r - 将字符列转换为 lubridate 中的日期列
- json - 将列转移到 JSON 末尾的 JOLT 规范
- python - XGboost - 网格搜索无法正常工作
- javascript - 我如何订购 React 中的组件
- google-analytics - 将 Google Analytics 360 链接到 Big Query,权限问题