NumPy:将'np.save()'与'allow_pickle = False'一起使用的后果

Sal*_*kot 11 python numpy

根据这里的 NumPy文档,默认情况下会保存一个矩阵allow_pickle=True,此外,它们会告诉这个默认行为可能有什么问题:

allow_pickle:bool,optional
允许使用Python pickles 保存对象数组.禁止泡菜的原因包括安全性(加载腌制数据可以执行任意代码)和可移植性(腌制对象可能无法在不同的Python安装上加载,例如,如果存储的对象需要不可用的库,并且并非所有的pickle数据都兼容Python 2和Python 3).
默认值:True

阅读之后,我当然更愿意使用allow_pickle=False- 但是当它以这种方式使用时,它们并没有说明有什么不同.allow_pickel=True尽管存在缺点,但默认情况下必须使用某些理由.

你能否告诉我你是否使用allow_pickle=False它以及它的表现如何?

wil*_*elm 8

对象数组只是一个普通的numpy数组,其中dtypeobject; 如果数组的内容不是正常的数字类型(如intfloat等),就会发生这种情况.我们可以试着用对象保存一个numpy数组,只是为了测试它是如何工作的.一种简单的对象是dict:

>>> import numpy as np
>>> a = np.array([{x: 1} for x in range(4)])
>>> a
array([{0: 1}, {1: 1}, {2: 1}, {3: 1}], dtype=object)
>>> np.save('test.pkl', a)
Run Code Online (Sandbox Code Playgroud)

装回这个工作正常:

>>> np.load('test.pkl.npy')
array([{0: 1}, {1: 1}, {2: 1}, {3: 1}], dtype=object)
Run Code Online (Sandbox Code Playgroud)

但是,如果不使用pickle,则无法保存数组:

>>> np.save('test.pkl', a, allow_pickle=False)
...
ValueError: Object arrays cannot be saved when allow_pickle=False
Run Code Online (Sandbox Code Playgroud)

泡菜的经验法则是,如果你正在加载你制作的泡菜,那么你是安全的,但你应该小心加载从其他地方获得的泡菜.首先,如果你没有安装用于制作pickle的相同库(或库版本),你可能无法加载pickle(这就是上面的可移植性意味着什么). 安全是另一个潜在的问题; 例如,您可以阅读一些关于如何在本文中滥用泡菜的内容.

  • 也许澄清一下(我在阅读时不清楚):在这种情况下,保存机器整数、浮点数等的 numpy 数组不需要酸洗,无论 allow_pickle 是什么,numpy 都不会使用酸洗。在不禁用 pickle 的情况下调用 load 仍然会通过故意制作的文件受到攻击。 (2认同)