Python - cPickle嵌套的datetime对象

时间:2013-01-14 23:00:06

标签: python datetime pickle

我有一个列表列表,每个子列表看起来像这样:

a = [datetime.datetime(2012, 2, 1), datetime.datetime(2012, 2, 2), 'string', 4.00]
b = [datetime.datetime(2012, 3, 1), datetime.datetime(2012, 3, 4), 'another_string', 5.00]

list_of_lists = [a,b]

挑选名单:

cPickle.dump(list_of_lists, open(filename, 'wb')) #filename defined 

运行时,会引发:

Traceback (most recent call last):
  File "analyze_data.py", line 129, in <module>
    analyze_data(sys.argv[1]) #because the dump runs inside a function
  File "analyze_data.py", line 77, in analyze_data
    cPickle.dump(list_of_lists, open(filename, 'wb')) 
TypeError: 'datetime.datetime' object is not callable

我在Python 2.7.3和2.6.8上复制了错误。

与常规泡菜相同的错误/追溯。此外,紧接在cPickle.dump之前的打印语句表明错误发生在此处而不是其他地方。

docs开始,听起来你可以cPickle嵌套对象,而不是所有嵌套对象都必须是内置类型。也许我可以将所有datetime个对象更改为字符串。毫无疑问,有很多方法可以完成序列化,我可以调整代码,使上述内容成为非问题。但是,我需要理解为什么它不可能,如果确实如此。

有人可以解释为什么嵌套的日期时间对象不能通过cPickle / pickle序列化吗?

编辑:在函数外部修剪上述数据结构很好。里面,没有骰子。见下文。

def analyze_data(some_id, some_date=default_date): #some_id/some_date (datetime object) defined above
  …
  #create list_of_lists
  …
  string_date = some_date.strftime('%Y%m%d') #works
  filename = '{0}_{1}.p'.format(some_id, string_date) #filename created fine
  cPickle.dump(list_of_lists, open(filename, 'wb')) #kaboom

我将此函数映射到其他模块中的其他数据,因此理想情况下希望将酸洗保留在函数调用中。

2 个答案:

答案 0 :(得分:0)

使用python2.7 test.py运行以下内容:

# encoding: utf-8
# SO 14328382
import cPickle
import datetime

default_date = datetime.datetime.now()

def analyze_data(some_id, some_date=default_date): #some_id/some_date (datetime object) defined above
    #…
    #create list_of_lists
    #…
    a = [datetime.datetime(2012, 2, 1), datetime.datetime(2012, 2, 2), 'string', 4.00]
    b = [datetime.datetime(2012, 3, 1), datetime.datetime(2012, 3, 4), 'another_string', 5.00]
    list_of_lists = [a,b]

    string_date = some_date.strftime('%Y%m%d') #works
    filename = '{0}_{1}.p'.format(some_id, string_date) #filename created fine
    cPickle.dump(list_of_lists, open(filename, 'wb')) #kaboom

analyze_data('abc', datetime.datetime(2013,3,12))

不会抛出错误,但会生成包含内容的文件abc_20130312.p

(lp1
(lp2
cdatetime
datetime
p3
(S'\x07\xdc\x02\x01\x00\x00\x00\x00\x00\x00'
tRp4
ag3
(S'\x07\xdc\x02\x02\x00\x00\x00\x00\x00\x00'
tRp5
aS'string'
p6
aF4
aa(lp7
g3
(S'\x07\xdc\x03\x01\x00\x00\x00\x00\x00\x00'
tRp8
ag3
(S'\x07\xdc\x03\x04\x00\x00\x00\x00\x00\x00'
tRp9
aS'another_string'
p10
aF5
aa.

所以从那里开始慢慢扩展它,看看你的代码在哪里断开。

答案 1 :(得分:0)

要做到这一点,我不会做任何复杂的事情...我会编写你想写的代码。我使用dill,它可以在python中序列化几乎任何东西。

>>> import dill
>>> import datetime
>>> a = [datetime.datetime(2012, 2, 1), datetime.datetime(2012, 2, 2), 'string', 4.00]
>>> b = [datetime.datetime(2012, 3, 1), datetime.datetime(2012, 3, 4), 'another_string', 5.00]
>>> 
>>> list_of_lists = [a,b]
>>> 
>>> lol = dill.loads(dill.dumps(list_of_lists))
>>> lol
[[datetime.datetime(2012, 2, 1, 0, 0), datetime.datetime(2012, 2, 2, 0, 0), 'string', 4.0], [datetime.datetime(2012, 3, 1, 0, 0), datetime.datetime(2012, 3, 4, 0, 0), 'another_string', 5.0]]
>>>
>>> default_date = datetime.datetime.today()
>>> 
>>> def analyze_data(some_id, some_date=default_date):
...     string_date = some_date.strftime('%Y%m%d')
...     filename = '{0}_{1}.p'.format(some_id, string_date)
...     return dill.loads(dill.dumps(list_of_lists))
... 
>>> # no kaboom
>>> analyze_data('123')
[[datetime.datetime(2012, 2, 1, 0, 0), datetime.datetime(2012, 2, 2, 0, 0), 'string', 4.0], [datetime.datetime(2012, 3, 1, 0, 0), datetime.datetime(2012, 3, 4, 0, 0), 'another_string', 5.0]]

Dill还有some good tools帮助您了解代码失败时导致酸洗失败的原因。