考虑下面的Python代码:
import cloudpickle
class Foo:
def __init__(self, num):
self.num = num
def outer(num):
return Foo(num)
print(cloudpickle.dumps(outer))
这会在每次运行代码时产生不同的pickle。使用pickletools
分析pickle文件显示以下差异:
144c144
< 552: \x8c SHORT_BINUNICODE '2e3db4572bb349268962a75a8a6f034c'
---
> 552: \x8c SHORT_BINUNICODE '89ee770de9b745c4bbe83c353f1debba'
现在,我知道cloudpickle不能保证pickle文件的确定性。(link),但我很好奇为什么这两个pickle文件不同。上面的差异似乎是由于Foo
类的某种不同哈希造成的
注意,我使用固定的PYTHONHASHSEED
运行python程序
附言: 这足以重现问题:
import pickletools
import cloudpickle
class Foo:
def __init__(self, num):
self.num = num
pickletools.dis(cloudpickle.dumps(Foo))
因此,似乎每个类都有一个属性,该属性被烘焙到cloudpickle中,但我不知道该属性是什么
好奇
我深入研究了源代码,发现它不是类的属性,甚至不是计算的哈希,而是just a random identifier generated with ^{} per class
该函数由^{} here 调用,该函数由具有注释的^{} here 调用
如果类不在
__main__
模块中,事情就不会那么复杂了(因为__main__
从最终的unpickler的角度来看可能是任何东西);如果你做了from b import outer
和cloudpickle那outer
,你会得到就像泡菜,而不是巫毒云泡菜,用来泡菜
__main__
中的东西一样相关问题 更多 >
编程相关推荐