Skip to main content
 首页 » 编程设计

Python之cPickle 嵌套日期时间对象

2025年05月04日9sxdcgaq8080

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

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] 

pickle 列表:

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 上复制了错误。

常规 pickle 也有相同的错误/回溯。此外,紧接在 cPickle.dump 之前的打印语句表明错误发生在这里而不是其他地方。

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

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

编辑:pickling 上面的数据结构在函数外工作正常。里面没有骰子。见下文。

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 

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

请您参考如下方法:

使用 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. 

因此,从那里开始,慢慢扩展它,看看您的代码在哪里中断。