Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python pickle不是一对一:不同的pickle提供相同的对象_Python_Serialization_Pickle - Fatal编程技术网

Python pickle不是一对一:不同的pickle提供相同的对象

Python pickle不是一对一:不同的pickle提供相同的对象,python,serialization,pickle,Python,Serialization,Pickle,有人能解释一下吗 pickle.loads(b'\x80\x03X\x01\x00\x00\x00.q\x00h\x00\x86q\x01.') == pickle.loads(b'\x80\x03X\x01\x00\x00\x00.q\x00X\x01\x00\x00\x00.q\x01\x86q\x02.') >>>True pickle.loads(b'\x80\x03X\x01\x00\x00\x00.q\x00h\x00\x86q\x01.') >>&g

有人能解释一下吗

pickle.loads(b'\x80\x03X\x01\x00\x00\x00.q\x00h\x00\x86q\x01.') == pickle.loads(b'\x80\x03X\x01\x00\x00\x00.q\x00X\x01\x00\x00\x00.q\x01\x86q\x02.')
>>>True

pickle.loads(b'\x80\x03X\x01\x00\x00\x00.q\x00h\x00\x86q\x01.')
>>>('.', '.')
pickle.loads(b'\x80\x03X\x01\x00\x00\x00.q\x00X\x01\x00\x00\x00.q\x01\x86q\x02.')
>>>('.', '.')
似乎存在重复使用同一元素的长元组和短元组

其他例子:

pickle.loads(b'\x80\x03X\x01\x00\x00\x00#q\x00X\x01\x00\x00\x00#q\x01\x86q\x02.')
>>>('#', '#')
pickle.loads(b'\x80\x03X\x01\x00\x00\x00#q\x00h\x00\x86q\x01.')
>>>('#', '#')

pickle.loads(b'\x80\x03X\x01\x00\x00\x00$q\x00X\x01\x00\x00\x00$q\x01\x86q\x02.')
>>>('$', '$')
pickle.loads(b'\x80\x03X\x01\x00\x00\x00$q\x00h\x00\x86q\x01.')
>>>('$', '$')
我试图按项目的pickle索引项目,但我找不到这些项目,因为它们的pickle似乎在变化


我正在Ubuntu上使用Python 3.3.2。

pickle不是唯一的;pickle格式实际上是一个函数,不同的程序pickle可以生成相同的输出非pickle对象。从文档中:

由于pickle数据格式实际上是一种面向堆栈的小型编程语言,并且在某些对象的编码中有一定的自由度,因此两个模块[pickle和cPickle]可能会为相同的输入对象生成不同的数据流。但是,可以保证它们始终能够读取彼此的数据流


甚至有一个函数可以接受一个pickle并输出一个更好的pickle。你需要重新设计你的程序。

泡菜不是唯一的;pickle格式实际上是一个函数,不同的程序pickle可以生成相同的输出非pickle对象。从文档中:

由于pickle数据格式实际上是一种面向堆栈的小型编程语言,并且在某些对象的编码中有一定的自由度,因此两个模块[pickle和cPickle]可能会为相同的输入对象生成不同的数据流。但是,可以保证它们始终能够读取彼此的数据流


甚至有一个函数可以接受一个pickle并输出一个更好的pickle。您需要重新设计您的程序。

那么如何将对象转换为规范索引?@mtanti:取决于您的用例。您可能不需要这样做,或者您可以使用id,或者repr可能是合适的,或者您可以编写自定义代码。@mtanti:如果您的对象是两个字符串的元组……这已经是一个很好的索引了。它是不可变的和可散列的,使用任何合理的持久性格式存储和恢复它,包括pickle,保证提供一个相等的对象,等等。user2357112@abarnert我正在开发一个存储任意数据的数据库,我将其存储为pickle。@mtanti:开发数据库是什么意思?创建自己的数据库引擎是为了直接存储Python对象,并希望能够在数据库上执行Python表达式?或者仅仅使用sqlite或MySQL之类的数据库引擎来存储Python对象?那么如何将对象转换为规范索引?@mtanti:取决于您的用例。您可能不需要这样做,或者您可以使用id,或者repr可能是合适的,或者您可以编写自定义代码。@mtanti:如果您的对象是两个字符串的元组……这已经是一个很好的索引了。它是不可变的和可散列的,使用任何合理的持久性格式存储和恢复它,包括pickle,保证提供一个相等的对象,等等。user2357112@abarnert我正在开发一个存储任意数据的数据库,我将其存储为pickle。@mtanti:开发数据库是什么意思?创建自己的数据库引擎是为了直接存储Python对象,并希望能够在数据库上执行Python表达式?或者仅仅使用sqlite或MySQL之类的数据库引擎来存储Python对象?请观察pickle.dumps'',3==b'\x80\x03X\x01\x00\x00\x00.q\x00',以及序列X\x01\x00\x00\x00。在较长的“.”、“.”酸洗版本中发生两次,在较短版本中仅发生一次。虽然我不读pickle格式,但我认为这里有一个pickle文件,它两次表示包含相同字符串的元组,另一个表示包含两个恰好相等字符串的元组。在Python实现中的短字符串交互可能会在非酸洗过程中消除这种差异,但即使不是,它们在打印时也是相同的。考虑一个可能会问的广义等价问题:我用JSON表示对对象进行索引,但是[1, 1 ]和[1, 1 ]。是同一对象的不同JSON表示形式。JSON是一种非常简单的格式,规范化它非常简单:使空白规则化,在字典中对键排序,仅此而已。pickle格式不那么简单,一般来说,对于类型,您将很难识别和实习相等的值。您可以使用集合来存储任何可散列数据的规范版本,但并非所有可pickle的数据都是可散列的。@SteveJessop那么如何在数据库中存储和搜索任意数据呢?我将数据存储为pickle,然后在搜索之前对搜索查询进行pickle。您不会这样做。数据库中两个值的相等定义必须与数据库能够看到的相等匹配。因此,您可以在数据库中存储和搜索结构化数据。如果你找不到一种方法来组织你的数据,那么你就会遇到一个相当困难的问题,在某些情况下,这是其他方法无法解决的
我注意到shelve只允许字符串作为键。这解释了很多。尽管如此,我仍然认为不将pickle规范化是相当愚蠢的,它们那时会更有用。观察pickle.dumps'',3==b'\x80\x03X\x01\x00\x00\x00\x00.q\x00',以及序列X\x01\x00\x00。在较长的“.”、“.”酸洗版本中发生两次,在较短版本中仅发生一次。虽然我不读pickle格式,但我认为这里有一个pickle文件,它两次表示包含相同字符串的元组,另一个表示包含两个恰好相等字符串的元组。在Python实现中的短字符串交互可能会在非酸洗过程中消除这种差异,但即使不是,它们在打印时也是相同的。考虑一个可能会问的广义等价问题:我用JSON表示对对象进行索引,但是[1, 1 ]和[1, 1 ]。是同一对象的不同JSON表示形式。JSON是一种非常简单的格式,规范化它非常简单:使空白规则化,在字典中对键排序,仅此而已。pickle格式不那么简单,一般来说,对于类型,您将很难识别和实习相等的值。您可以使用集合来存储任何可散列数据的规范版本,但并非所有可pickle的数据都是可散列的。@SteveJessop那么如何在数据库中存储和搜索任意数据呢?我将数据存储为pickle,然后在搜索之前对搜索查询进行pickle。您不会这样做。数据库中两个值的相等定义必须与数据库能够看到的相等匹配。因此,您可以在数据库中存储和搜索结构化数据。如果你找不到一种方法来构造你的数据,那么你就会遇到一个相当困难的问题,在某些情况下,除了将逻辑移出数据库之外,这是无法解决的。我刚刚注意到shelve只允许字符串作为键。这解释了很多。尽管如此,我认为不把泡菜规范化是相当愚蠢的,那时泡菜会更有用。