【问题标题】:ImportError: No module named copy_reg pickleImportError:没有名为 copy_reg pickle 的模块
【发布时间】:2009-02-17 10:42:58
【问题描述】:

我正在尝试解开存储为 MySQL 数据库中 blob 的对象。我已经手动生成了腌制对象并将其存储在数据库中,但是当我尝试取消腌制对象时,我得到了以下相当神秘的异常:

ImportError: 没有名为 copy_reg 的模块

关于为什么会发生这种情况的任何想法?

繁殖方法

注意:必须在 Windows PC 上执行步骤 1,在 Linux PC 上执行步骤 3 和 4。

1) 在 Windows PC 上:

file = open("test.txt", "w")
thing = {'a': 1, 'b':2}
cPickle.dump(thing, file)

2) 手动将 text.txt 的内容插入到 Linux 上运行的 MySQL 数据库的 blob 字段中

3) 在Linux机器上运行的Python中,从MySQL获取列的内容

4) 假设您将 blob 列的内容放入一个名为 data 的变量中,试试这个:

cPickle.loads(rawString)

【问题讨论】:

  • 你用的是什么版本的python?
  • 这是 Python 2.4
  • 在这种情况下代码会添加什么?
  • @Stephen Edmonds:由于没有代码,我不得不假设您使用的是什么代码。可悲的是,我假设的代码运行良好,所以我无法重现你的问题。如果我有你的代码,而不是我的,我可能会提供帮助。
  • @S.Lott:我现在添加了代码 sn-ps,但正如您所见,它们并没有太大帮助。问题难以重现的主要原因是您需要在 Windows 上腌制对象,将其保存到文件中,然后尝试在 Linux 上取消腌制。

标签: python pickle


【解决方案1】:

看来这可能是我导出腌制对象的方法造成的。

This bug report 认为我的问题可以通过导出到以二进制模式写入的文件来解决。我现在就试一试,看看这是否能解决我的问题。

更新:这行得通。解决方案是确保将腌制对象导出到以二进制模式打开的文件中,即使您使用的是默认协议 0(通常称为“文本”)

基于相关原始示例的正确代码:

file = open("test.txt", 'wb')
thing = {'a': 1, 'b':2}
cPickle.dump(thing, file)

【讨论】:

  • 再一次,代码究竟会显示什么?对这个答案有什么好处?
  • 如果只想提到No module named copy_reg pickle 也可以是任何其他模块名称,例如我的情况。这可能会在调试过程中造成混淆。
【解决方案2】:

另外,简单地在(windows 创建的)pickle 文件上运行 dos2unix(在 linux 下)为我解决了这个问题。 (还没有尝试过打开模式'wb'的东西。) 丹

【讨论】:

  • 这应该是一个asnwer
【解决方案3】:

只是一个交互式 python 会话,表明您不需要任何特定的代码来解决这个问题:

在 Windows 机器上做这样的事情

Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle, re
>>> empty_string = re.compile("^$")
>>> pickle.dump([empty_string,1,1.23,'abc'], file('m:/mario/test-b.dump','wb'))
>>> pickle.dump([empty_string,1,1.23,'abc'], file('m:/mario/test-t.dump','wt'))
>>> 

然后尝试从 linux 机器中检索数据

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) 
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> pickle.load(file('/home/mario/.gvfs/transfer on 192.168.0.4/mario/test-b.dump'))
/usr/lib/python2.6/pickle.py:1124: DeprecationWarning: The sre module is deprecated, please import re.
  __import__(module)
[<_sre.SRE_Pattern object at 0xb7d42420>, 1, 1.23, 'abc']
>>> pickle.load(file('/home/mario/.gvfs/transfer on 192.168.0.4/mario/test-t.dump'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/pickle.py", line 1370, in load
    return Unpickler(file).load()
  File "/usr/lib/python2.6/pickle.py", line 858, in load
    dispatch[key](self)
  File "/usr/lib/python2.6/pickle.py", line 1090, in load_global
    klass = self.find_class(module, name)
  File "/usr/lib/python2.6/pickle.py", line 1124, in find_class
    __import__(module)
ImportError: No module named sre
>>> 

如果您只是腌制基本类型,则错误消息可能会更加令人困惑。这就是我从列表中得到的[12, 1.2, '']

ValueError: insecure string pickle

【讨论】:

    【解决方案4】:

    正如在另一个答案中提到的那样使用

    dos2unix originalPickle.file outputPickle.file
    

    或使用下面的 tr 命令(删除回车和 ctrl-z)

      tr -d '\15\32' < originalPickle.file > outputPickle.file
    

    或使用awkgawknawk,如果是旧版本)

      awk '{ sub("\r$", ""); print }' originalPickle.file > outputPickle.file
    

    或者,如果您可以在 linux 中重新创建一个 pickle 文件,请使用它。

    【讨论】:

      【解决方案5】:

      这里发生的另一件事是,在将泡菜转储到文件后,您似乎没有关闭文件。此处报告的错误有时可能是由不关闭文件引起的(无论是在 Windows 机器上还是在其他情况下)。

      【讨论】:

        【解决方案6】:

        我的问题:

        with open('model.pkl', 'rb') as f:
            subsection_struct_model = pickle.load(f)
        

        当我从 windows 获取 model.pkl 在我的 mac 中运行此代码时,此问题即将出现

        解决:

        dos2unix model.pkl 
        

        没问题!

        【讨论】:

          【解决方案7】:

          这是因为在Windows中,换行符存储为“\r\n”,而在Linux中是“\n”,所以你应该做的是逐行读取pickle文件,替换“\ r\n" 与 "\n",并将其写回文件。

          与 dos2unix 方法会跳过二进制文件不同,这也适用于二进制 pickle 文件。

          代码很简单:

          #run this code on Linux platform
          
          DIR="your/dir/to/file"
          
          pickle.load(open(DIR,"rb"))
          # ImportError: No module named copy_reg pickle
          
          a=open(DIR,"rb").readlines() #read pickle file line by line
          
          a=map(lambda x:x.replace("\r\n","\n"),a) # replace \r\n with \n
          
          with open(DIR,"wb") as j: #write back to file in binary mode
              for i in a:
                  j.write(i)         
          pickle.load(open(DIR,"rb")) 
          #Now it works well
          

          另外,您可以使用普通写入模式,只需将“wb”更改为“w”,将“rb”更改为“e”即可。

          【讨论】:

          • 直截了当的回答。作品!谢谢!
          【解决方案8】:

          我遇到了这个问题,因为 git 改变了 Windows 上的行尾。

          我通过将.gitattributes 文件添加到我的存储库中解决了这个问题:

          # Pickle files (for testing) should always have UNIX line endings. 
          *.pkl text eol=lf
          

          另见https://github.com/actions/checkout/issues/135

          【讨论】:

            【解决方案9】:

            pickle 加载可能与您的 python 脚本不在同一位置。有时目录会根据您的应用程序而更改。在加载泡菜之前,打印一个 os.getcwd() 来制定解决方案。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-04-15
              • 2021-04-23
              • 1970-01-01
              • 2013-03-11
              • 2012-12-07
              • 2012-05-23
              • 2019-07-29
              • 2015-07-04
              相关资源
              最近更新 更多