在解压缩在Linux上创建的对象和(尝试)在Windows上进行unpickle时,我遇到模块依赖性故障。 pickle在Linux中正确地解开,但在Windows中失败了。两个系统都运行Python 2.6。
我研究了泡菜手册页(特别注重使泡菜环境与泡菜环境相同),以及几条很棒的建议 - 但我仍然难过。大多数人都建议确保sys.modules正确并加载。以下是一些显示我正在尝试的内容的片段:
酸洗代码:
...
pickle_fp = self.getPickleFile('wb')
pickler = Pickler(pickle_fp, protocol=2)
pickler.dump(archive)
pickle_fp.close()
...
在unpickling代码中,我添加了一行来打印出sys.modules字典,以便我们可以看到存在的模块:
...
pickle_fp = self.getPickleFile('rb')
unpickler = Unpickler(pickle_fp)
pprint.pprint(sys.modules)
package = unpickler.load()
pickle_fp.close()
...
当我在Linux中运行unpickle时它工作得很好。当我尝试在Windows上解压缩在Linux上生成的pickle时,我得到:
...
ImportError: No module named photo_data
对于环境,pprint.pprint(sys.modules)
在Linux上生成
...
'photo_data': <module 'photo_data' from
'/home/xxx/Desktop/PythonPhoto/photo_data.pyc'>,
...
并在Windows上
...
'photo_data': <module 'photo_data' from
'C:\Users\xxx\git\PhotoManagement\Photo\src\photo_data.pyc'>,
...
所以在我看来,我在环境中拥有photo_data
模块。我尝试使用没有协议的pickle(默认为0),我尝试运行unix2dos来删除字符。我正式难过。
感谢您的帮助!
根据评论中的建议,我生成了最简单的案例。我正在腌制的课程看起来像这样:
class photo_data:
def __init__(self):
self.isdir = False
self.size = 0
self.mtime = -(sys.maxint - 1) #Set default time to very old
self.timestamp = datetime.datetime.strptime('1700:1:1 00:00:00', '%Y:%m:%d %H:%M:%S')
self.gotTags = False
self.signature = ''
self.fileMD5 = ''
self.userTags = ''
self.inArchive = False
self.candidates = []
self.dirpaths = []
self.filepaths = []
class photo_collection: #This class should be data only
def __init__(self):
self.host = ''
self.path = ''
self.photo = dict()
self.pickle = None
self.datasetChanged = False
def __getitem__(self, key):
return self.photo[key]
def __setitem__(self, key, value):
self.photo[key] = value
在我的用例中,photo_collection
对象被实例化,而字典self.photo
则填充了photo_data
的实例。在系统之间工作的最简单的情况是其中包含一张照片的目录,并且任意复杂的案例在系统中。在系统之间不起作用的最简单的情况是一个目录,其中包含一张照片和一个包含照片的子目录。
根据请求,我附加了format = 0
中保存的两个pickle文件。如果你比较它们,我看到程序以不同的顺序下降文件树(可能不是一个大惊喜,因为我在系统和操作系统之间复制了目录),但是否则它们似乎打开和关闭的结构与文件相同 - 具体数据。我没有看到如何将文件上传到单独的地方,所以我在这里将它们包含在内。
这是Windows生成的泡菜:
(iphoto_data
photo_collection
p0
(dp1
S'path'
p2
S'C:\\Users\\scott_jackson\\Desktop\\phototest'
p3
sS'host'
p4
S'4DAA1001312'
p5
sS'pickle'
p6
NsS'datasetChanged'
p7
I01
sS'photo'
p8
(dp9
S'C:\\Users\\scott_jackson\\Desktop\\phototest\\img_4697.jpg'
p10
(iphoto_data
photo_data
p11
(dp12
S'isdir'
p13
I00
sS'dirpaths'
p14
(lp15
sS'filepaths'
p16
(lp17
sS'timestamp'
p18
cdatetime
datetime
p19
(S'\x07\xda\x04\x12\x124&\x00\x00\x00'
p20
tp21
Rp22
sS'gotTags'
p23
I01
sS'signature'
p24
S'9b2ca527b2bf0865d9b87ecd2a68d417'
p25
sS'fileMD5'
p26
S''
p27
sS'candidates'
p28
(lp29
sS'mtime'
p30
F1347576558.0
sS'inArchive'
p31
I00
sS'userTags'
p32
S'NA'
p33
sS'size'
p34
L6489323L
sbsg3
(iphoto_data
photo_data
p35
(dp36
g13
I01
sg14
(lp37
S'C:\\Users\\scott_jackson\\Desktop\\phototest\\060101 Nags Head'
p38
asg16
(lp39
g10
asg18
g19
(S'\x06\xa4\x01\x01\x00\x00\x00\x00\x00\x00'
p40
tp41
Rp42
sg23
I00
sg24
g27
sg26
g27
sg28
(lp43
sg30
I-2147483646
sg31
I00
sg32
g27
sg34
I0
sbsS'C:\\Users\\scott_jackson\\Desktop\\phototest\\060101 Nags Head\\img_1150.jpg'
p44
(iphoto_data
photo_data
p45
(dp46
g13
I00
sg14
(lp47
sg16
(lp48
sg18
g19
(S'\x07\xd6\x01\x01\x11\t#\x00\x00\x00'
p49
tp50
Rp51
sg23
I01
sg24
S'5925063685af0d741a23fe6d75523741'
p52
sg26
g27
sg28
(lp53
sg30
F1347751812.0
sg31
I00
sg32
g33
sg34
L538233L
sbsS'C:\\Users\\scott_jackson\\Desktop\\phototest\\060101 Nags Head'
p54
(iphoto_data
photo_data
p55
(dp56
g13
I01
sg14
(lp57
sg16
(lp58
g44
asg18
g19
(S'\x06\xa4\x01\x01\x00\x00\x00\x00\x00\x00'
p59
tp60
Rp61
sg23
I00
sg24
g27
sg26
g27
sg28
(lp62
sg30
I-2147483646
sg31
I00
sg32
g27
sg34
I0
sbssb.
这是Linux生成的泡菜:
(iphoto_data
photo_collection
p0
(dp1
S'path'
p2
S'/home/scott/phototest'
p3
sS'host'
p4
S'barney'
p5
sS'pickle'
p6
NsS'datasetChanged'
p7
I01
sS'photo'
p8
(dp9
S'/home/scott/phototest/060101 Nags Head/img_1150.jpg'
p10
(iphoto_data
photo_data
p11
(dp12
S'isdir'
p13
I00
sS'dirpaths'
p14
(lp15
sS'filepaths'
p16
(lp17
sS'timestamp'
p18
cdatetime
datetime
p19
(S'\x07\xd6\x01\x01\x11\t#\x00\x00\x00'
p20
tp21
Rp22
sS'gotTags'
p23
I01
sS'signature'
p24
S'5925063685af0d741a23fe6d75523741'
p25
sS'fileMD5'
p26
S''
p27
sS'candidates'
p28
(lp29
sS'mtime'
p30
F1347751812.0842018
sS'inArchive'
p31
I00
sS'userTags'
p32
S'NA'
p33
sS'size'
p34
I538233
sbsS'/home/scott/phototest/060101 Nags Head'
p35
(iphoto_data
photo_data
p36
(dp37
g13
I01
sg14
(lp38
sg16
(lp39
g10
asg18
g19
(S'\x06\xa4\x01\x01\x00\x00\x00\x00\x00\x00'
p40
tp41
Rp42
sg23
I00
sg24
g27
sg26
g27
sg28
(lp43
sg30
I-9223372036854775806
sg31
I00
sg32
g27
sg34
I0
sbsS'/home/scott/phototest/img_4697.jpg'
p44
(iphoto_data
photo_data
p45
(dp46
g13
I00
sg14
(lp47
sg16
(lp48
sg18
g19
(S'\x07\xda\x04\x12\x124&\x00\x00\x00'
p49
tp50
Rp51
sg23
I01
sg24
S'9b2ca527b2bf0865d9b87ecd2a68d417'
p52
sg26
g27
sg28
(lp53
sg30
F1347576558.5344362
sg31
I00
sg32
g33
sg34
I6489323
sbsg3
(iphoto_data
photo_data
p54
(dp55
g13
I01
sg14
(lp56
S'/home/scott/phototest/060101 Nags Head'
p57
asg16
(lp58
g44
asg18
g19
(S'\x06\xa4\x01\x01\x00\x00\x00\x00\x00\x00'
p59
tp60
Rp61
sg23
I00
sg24
g27
sg26
g27
sg28
(lp62
sg30
I-9223372036854775806
sg31
I00
sg32
g27
sg34
I0
sbssb.
请随意将这些内容粘贴到您最喜欢的“比较”编辑器中;我不太了解泡菜来发现问题。
先谢谢你的帮助!!
答案 0 :(得分:1)
我通过在Mac OS X机器上保存带有CRLF(Windows)行结尾的pickle来重现您的问题。
泡菜机械在新品上非常讲究。如果使用非二进制传输模式保存或复制pickle(例如,在Windows上使用文本编辑器重新保存,使用ASCII FTP传输复制,从网站保存为文本文件等),则pickle 将是已损坏并添加了CR字符。
现在,问题是pickle.py中的这一行:
module = self.readline()[:-1]
如果您为Unpickler
提供的文件已打开'rb'
但包含CRLF,则这些行将显示module = "photo_data\r"
,这不是有效的模块名称。导入后,错误将显示为
ImportError: No module named photo_data
在photo_data
之后使用未打印的回车(非常偷偷摸摸!)。
解决方案是确保以二进制方式传输文件,不运行unix2dos
或pickle上的任何类似实用程序。或者,如果使用协议0(文本)泡菜,则可以安全地使用'rU'
(通用换行模式)来打开pickle文件。
答案 1 :(得分:1)
今天我遇到了类似的问题:由于CRLF行结尾,在linux上被腌制的对象无法加载到Windows上,正如 @nneonneo 在他的回答中解释的那样。
问题是git认为.pkl
对象是文本文件,它应该规范化行结尾。因此,当我在linux机器上使用二进制.pkl
文件推送项目,并将它们拉到windows机器上时,行结束是CRLF而不是unix行结束。解决方案是使用
.gitattributes
文件添加到存储库中
*.pkl binary
强制git完全不操纵文件。
然后,您可以按照建议here“刷新”更改。我在Windows机器上再次删除并克隆了项目。