了解 Python 中的命名元组类型名和 pickle 的问题

2024-04-15

今天早些时候,我在尝试腌制时遇到了麻烦命名元组 http://docs.python.org/2/library/collections.html#namedtuple-factory-function-for-tuples-with-named-fields实例。作为健全性检查,我尝试运行一些发布的代码在另一个答案中 https://stackoverflow.com/a/16377267/553404。在这里,稍微简化一下:

from collections import namedtuple
import pickle

P = namedtuple("P", "one two three four")

def pickle_test():
    abe = P("abraham", "lincoln", "vampire", "hunter")
    f = open('abe.pickle', 'w')
    pickle.dump(abe, f)
    f.close()

pickle_test()

然后我更改了其中的两行以使用我的命名元组:

from collections import namedtuple
import pickle

P = namedtuple("my_typename", "A B C")

def pickle_test():
    abe = P("ONE", "TWO", "THREE")
    f = open('abe.pickle', 'w')
    pickle.dump(abe, f)
    f.close()

pickle_test()

然而这给了我错误

  File "/path/to/anaconda/lib/python2.7/pickle.py", line 748, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <class '__main__.my_typename'>: it's not found as __main__.my_typename

即 Pickle 模块正在寻找my_typename。我改变了线路P = namedtuple("my_typename", "A B C") to P = namedtuple("P", "A B C")它起作用了。

我查看了来源namedtuple.py最后我们得到了一些看起来相关的东西,但我不完全理解发生了什么:

# For pickling to work, the __module__ variable needs to be set to the frame
# where the named tuple is created.  Bypass this step in enviroments where
# sys._getframe is not defined (Jython for example) or sys._getframe is not
# defined for arguments greater than 0 (IronPython).
try:
    result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
except (AttributeError, ValueError):
    pass

return result

所以我的问题是到底发生了什么?为什么typename参数需要与工厂名称匹配才能正常工作吗?


在标题为什么可以腌制和不腌制? https://docs.python.org/3/library/pickle.html#what-can-be-pickled-and-unpickledPython 文档指出只有“在模块顶层定义的类”可以被 pickle。然而namedtuple() https://docs.python.org/3/library/collections.html#namedtuple-factory-function-for-tuples-with-named-fields是一家工厂function这有效地定义了一个类(my_typename(tuple)在你的第二个例子中),但是它没有将制造类型分配给名为的变量my_typename在模块的顶层。

这是因为pickle仅保存此类事物的“完全限定”名称,而不保存它们的代码,并且它们必须是import能够从他们所在的模块中使用这个名称,以便以后能够解封(因此要求模块必须在顶层包含命名对象)。

这可以通过解决该问题的一种解决方法来说明,即更改一行代码,以便名为my_typename is在顶层定义:

P = my_typename = namedtuple("my_typename", "A B C")

或者,您可以只给出namedtuple名字"P"代替"my_typename":

P = namedtuple("P", "A B C")

至于那是什么namedtuple.py您正在查看的源代码的作用是:它试图确定调用者(模块的创建者)的名称namedtuple)是因为作者知道pickle可能会尝试用它来import进行 unpickling 的定义,人们通常将结果分配给与传递给工厂函数同名的变量(但在第二个示例中没有这样做)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解 Python 中的命名元组类型名和 pickle 的问题 的相关文章

  • 如何使用 conda 在一行中安装多个包?

    我需要使用 conda 安装以下多个软件包 我不确定 conda forge 是什么 有些使用 conda forge 有些不使用它 是否可以将它们安装成一行而不需要一一安装 谢谢 conda install c conda forge d
  • ca 证书 Mac OS X

    我需要在emacs 上安装offlineimap 和mu4e 问题是配置 当我运行 Offlineimap 时 我得到 OfflineIMAP 6 5 5 Licensed under the GNU GPL v2 v2 or any la
  • 最小二乘法拟合直线 python 代码

    我有一个由 X 和 Y 坐标组成的散点图 我想使用直线的最小二乘拟合来获得最佳拟合线 直线最小二乘拟合是指 如果 x 1 y 1 x n y n 是测量数据对 则最佳直线是y A Bx 这是我的Python代码 number of poin
  • Pandas 连接问题:列重叠但未指定后缀

    我有以下数据框 print df a mukey DI PI 0 100000 35 14 1 1000005 44 14 2 1000006 44 14 3 1000007 43 13 4 1000008 43 13 print df b
  • Paramiko SSHException 通道已关闭

    我一直在使用 Paramiko 在 Linux Windows 机器上发送命令 它可以很好地在 Ubuntu 机器上远程执行测试 但是 它不适用于 Windows 7 主机 以下是我收到的错误 def unit for event self
  • 将一维数组转换为下三角矩阵

    我想将一维数组转换为较低的零对角矩阵 同时保留所有数字 我知道numpy tril函数 但它用零替换了一些元素 我需要扩展矩阵以包含所有原始数字 例如 10 20 40 46 33 14 12 46 52 30 59 18 11 22 30
  • 对于相同的查询,MySQL Workbench 比 Python 快得多

    MySQL Workbench 中的以下查询需要 0 156 秒才能完成 SELECT date time minute price id FROM minute prices WHERE contract id 673 AND TIMES
  • Django 模型字段默认基于另一个模型字段

    我使用 Django Admin 构建一个管理站点 有两张表 一张是ModelA其中有数据 另一个是ModelB里面什么也没有 如果一个模型字段b b in ModelB为None 可以显示在网页上 值为ModelA的场a b 我不知道该怎
  • reStructuredText:README.rst 未在 PyPI 上解析

    我有一个托管在 Github 和 PyPI 上的 Python 项目 在 Github 上 https github com sloria TextBlob blob master README rst https github com s
  • 如何使用 PyMongo 在重复键错误后继续插入

    如果我需要在 MongoDB 中插入尚不存在的文档 db stock update one document set document upsert True 将完成这项工作 如果我错了 请随时纠正我 但是 如果我有一个文档列表并想将它们全
  • 在 Linux 上的 Python 中使用受密码保护的 Excel 工作表

    问题很简单 我每周都会收到一堆受密码保护的 Excel 文件 我必须解析它们并使用 Python 将某些部分写入新文件 我得到了文件的密码 当在 Windows 上完成此操作时 处理起来很简单 我只需导入 win32com 并使用 clie
  • 在 iPython/pandas 中绘制多条线会生成多个图

    我试图了解 matplotlib 的状态机模型 但在尝试在单个图上绘制多条线时遇到错误 据我了解 以下代码应该生成包含两行的单个图 import pandas as pd import pandas io data as web aapl
  • Pandas groupby apply 执行缓慢

    我正在开发一个涉及大量数据的程序 我正在使用 python pandas 模块来查找数据中的错误 这通常工作得非常快 然而 我当前编写的这段代码似乎比应有的速度慢得多 我正在寻找一种方法来加快速度 为了让你们正确测试它 我上传了一段相当大的
  • uri 警告中缺少端口:使用 Python OpenCV cv2.VideoCapture() 打开文件时出错

    当我尝试流式传输 ipcam 时 出现了如下所示的错误 tcp 000000000048c640 uri 中缺少端口 警告 打开文件时出错 build opencv modules videoio src cap ffmpeg impl h
  • 在seaborn中对箱线图x轴进行排序

    我的数据框round data看起来像这样 error username task path 0 0 02 n49vq14uhvy93i5uw33tf7s1ei07vngozrzlsr6q6cnh8w 39 png 1 0 10 n49vq
  • 具有多个主键的 SQLAlchemy 不会自动设置任何

    我有一个简单的表 class test Base tablename test id Column Integer primary key True title Column String def init self title self
  • 在 Python 中访问 argparse 的参数值

    我正在尝试为我的程序设置一些简单的标志参数 但无法弄清楚如何访问它们 我有 argparser parser argparse ArgumentParser description Simple PostScript Interpreter
  • 如何更改matplotlib中双头注释的头大小?

    Below figure shows the plot of which arrow head is very small 我尝试了下面的代码 但它不起作用 它说 引发 AttributeError 未知属性 s k 属性错误 未知属性头宽
  • 如何从 nltk 下载器中删除数据/模型?

    我在 python3 NLTK 中安装了一些 NLTK 包 通过nltk download 尝试过它们 但不需要它们 现在想删除它们 我怎样才能删除例如包large grammars来自我的 NLTK 安装 我不想删除完整的 NLTK 安装
  • 使用 SERVER_NAME 时出现 Flask 404

    在我的 Flask 配置中 我将 SERVER NAME 设置为 app example com 之类的域 我这样做是因为我需要使用url for with external网址 如果未设置 SERVER NAME Flask 会认为服务器

随机推荐