Pickle 没有 __reduce__ 方法的 dict 子类不会加载成员属性

2024-07-01

我需要确保dict只能接受某种类型的对象作为值。它也必须是可挑选的。 这是我的第一次尝试:

import pickle

class TypedDict(dict):
    _dict_type = None

    def __init__(self, dict_type, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._dict_type = dict_type

    def __setitem__(self, key, value):
        if not isinstance(value, self._dict_type):
            raise TypeError('Wrong type')
        super().__setitem__(key, value)

如果我用下面的代码测试它(python 3.5)

my_dict = TypedDict(int)
my_dict['foo'] = 98

with open('out.pkl', 'wb') as fin:
    pickle.dump(my_dict, fin)

with open('out.pkl', 'rb') as fin:
    out = pickle.load(fin)

我收到错误:TypeError: isinstance() arg 2 must be a type or tuple of types.
似乎没有加载正确的值_dict_type它改为使用默认值None.
另外,它似乎依赖于协议,就好像它可以正常工作一样protocol=0

但是,如果我覆盖__reduce__方法并调用 super 一切都会神奇地起作用。

def __reduce__(self):
    return super().__reduce__()

怎么可能呢?不应该是两个类(w/o__reduce__) 相等的?我缺少什么?


怎么可能呢?不应该是两个类(w/o__reduce__) 相等的?我缺少什么?

你错过了一个关键的步骤:如果没有__reduce__方法(或者如果失败!)它将使用其他方法来pickle你的类。所以一堂课__reduce__如果没有的话,就不会表现得像一个班级__reduce__(有几种特殊的方法具有类似的行为)!

在第一种情况下,它将默认为基本dict转储和加载,然后处理子类逻辑。所以它将使用几个创建字典__setitem__调用,然后设置实例属性。但你的__setitem__需要实例属性 _dict_type。如果没有则默认为类属性 None,这失败了

TypeError: isinstance() arg 2 must be a type or tuple of types

这就是为什么如果你想腌制你的东西它会起作用TypedDict没有__reduce__如果它不包含任何键值对。因为它不会调用__setitem__然后设置实例属性:

my_dict = TypedDict(int)

with open('out.pkl', 'wb') as fin:
    pickle.dump(my_dict, fin)

with open('out.pkl', 'rb') as fin:
    out = pickle.load(fin)

print(out._dict_type)   # int

另一方面,如果你实现你的__reduce__方法,因为与失败的普通字典不同__reduce__- 它确实适用于子类(但如果您不实现,则不会尝试__reduce__):

>>> d = {1: 1}
>>> dict.__reduce__(d)
TypeError: "can't pickle dict objects"

>>> d = TypedDict(int)
>>> dict.__reduce__(d)
(<function copyreg._reconstructor>,
 (__main__.TypedDict, dict, {}),
 {'_dict_type': int})
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Pickle 没有 __reduce__ 方法的 dict 子类不会加载成员属性 的相关文章

  • 多处理冻结计算机

    我通过使用多处理提高了执行时间 但我不确定 PC 的行为是否正确 它会冻结系统 直到所有进程完成 我使用的是 Windows 7 和 Python 2 7 也许我做错了 这就是我所做的 def do big calculation sub
  • 调用exe中定义的函数

    我需要知道一种从 python 脚本调用 exe 中定义的函数的方法 我知道如何从 py 文件调用整个 exe 除非您的 EXE 是 COM 对象 或者像 dll 那样专门导出某些函数 否则这是不可能的 对于 COM 方法 请查看以下资源
  • PyCharm 项目文件消失了

    我当时正在做一个 python 项目JetBrains PyCharm 2016 2 https www jetbrains com pycharm 在 Lubuntu 上 突然之间 我的所有项目文件都从 IDE 中消失了 我尝试了以下方法
  • TypedDict 中的 Python 任意键

    是否可以使用一组已知键创建 TypedDict 然后创建任意键的类型 例如 在 TypeScript 中 我可以这样做 interface Sample x boolean y number name string string Pytho
  • numpy 不规则跨步数组

    引用文档 http docs scipy org doc numpy reference arrays ndarray html internal memory layout of an ndarray关于内存中的 numpy 数组结构 N
  • 使派生类的方法异步

    我必须创建并使用从上游包派生的类 不可修改 我想要 需要在派生类中添加 修改一个应该是异步的方法 因为我需要在该方法中等待 websocket send recv 我尝试将异步添加到该方法 但我收到消息 从基类方法 我的方法来自派生类Run
  • Python 中的一维马哈拉诺比斯距离

    我一直在努力validate我的计算代码马哈拉诺比斯距离写在Python 并仔细检查以比较 OpenCV 中的结果 我的数据点均为 1 维 5 行 x 1 列 In OpenCV C 我成功计算了马哈拉诺比斯距离方面数据点的尺寸为上述尺寸
  • 使用python docx合并word文档

    我有几个单词文件 每个文件都有特定的内容 我想要一个片段来展示或帮助我弄清楚如何在使用 Python 时将单词文件合并到一个文件中docx图书馆 例如 在 pywin32 库中我执行了以下操作 rng self doc Range 0 0
  • 关闭Python线程以防止内存泄漏

    如何关闭 Python 线程以确保线程内内存中的所有内容都从内存中清除 目前 我有一个通过以下方式加入的线程列表 for t in threadlist t join 5 这些线程最初是通过循环传递给每个线程的参数列表来创建的myfunc它
  • 如何获取Python日志模块当前正在记录的文件?

    有没有办法做到这一点 如果logging config fileConfig some log 是setter 什么是getter 只是好奇这是否存在 对于我对单个文件日志的基本用法 这有效 logging getLoggerClass r
  • PySpark 将模型预测与未转换的数据对齐:最佳实践

    使用 PySpark 的 ML 模块 经常会发生以下步骤 在数据清理之后等 执行特征和目标转换管道 创建模型 从模型生成预测 将预测和原始数据集合并在一起 供业务用户和模型验证之用 摘取一段精简的代码片段 predictions model
  • 使用后禁用按钮

    最近我决定重写我的不和谐机器人并添加按钮 到目前为止我遇到的主要问题是我无法禁用按钮就在被按下之后人们被告知是关于button disabled True实际上 它会禁用该按钮 但它只是将其发送为禁用状态 因此永远无法按下它 我想要的是能够
  • 在 Django 中保存文件之前更改文件名

    我有下一个代码在 django admin 中上传时重命名我的文件 在 models py 中 def get file path instance filename ext filename split 1 filename s s uu
  • 一次将多个函数应用于 Pandas groupby 对象

    已经提出了这个问题的变体 参见这个问题 https stackoverflow com questions 40532024 pandas apply multiple functions of multiple columns to gr
  • PDFMiner - 迭代页面并将其转换为文本

    所以我试图从一些 PDF 中获取特定的文本 并且我将 Python 与 PDFMiner 一起使用 但由于 API 发生的更改而遇到了一些问题2013年11月 https github com euske pdfminer api chan
  • 相当于 C++ 中用于缓冲读取的 python 生成器

    Guido Van Rossum 在此展示了 Python 的简单性article http neopythonic blogspot com 2008 10 sorting million 32 bit integers in 2mb h
  • 用python划分两个数据框

    我有两个数据框 df1 and df2 df1 TIMESTAMP eq1 eq2 eq3 2016 05 10 13 20 00 40 30 10 2016 05 10 13 40 00 40 10 20 df2 TIMESTAMP eq
  • 使用 Python API 创建文件后如何立即从 Google Vault 导出下载文件?

    使用 Python API 我创建了一个导出 如何使用相同的授权服务下载导出中的 zip 文件 创建导出时 我可以看到 cloudStorageSink 的 bucketName 和 objectNames 但是我找不到任何有关如何使用创建
  • Pandas:获取重复索引

    给定一个数据帧 我想获取重复的索引 这些索引在列中没有重复的值 并查看哪些值不同 具体来说 我有这个数据框 import pandas as pd wget https www dropbox com s vmimze2g4lt4ud3 a
  • 在 Mac 上安装 TensorFlow 时出现问题

    我正在尝试遵循安装指南张量流组织 http www tensorflow org get started os setup md并因此使用 Homebrew 再次安装了 Python 版本 2 当我按照描述运行安装时 pip install

随机推荐