2

リストのリストがあり、各サブリストは次のようになります。

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 の直前の print ステートメントは、エラーが他の場所ではなくここで発生していることを示唆しています。

docsから、ネストされたオブジェクトを cPickle できるように思えますが、そのすべてが組み込み型である必要はありません。おそらく、すべての日時オブジェクトを文字列に変更できます。シリアル化を実現する方法はたくさんあることは間違いありません。コードを調整して、上記の問題が発生しないようにすることもできます。ただし、実際にそうである場合、なぜそれが不可能なのかを理解する必要があります。

ネストされた日時オブジェクトが 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

この関数を他のモジュールの他のデータにマップするので、理想的には、関数呼び出し内でピクルを維持したいと考えています。

4

2 に答える 2

0

これを行うために、複雑なことは何もしません... あなたが書きたいと思ったコードを書きます。Pythonでほとんど何でもシリアル化できるdillを使用します。

>>> 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 には、コードが失敗したときに pickle 化が失敗する原因を理解するのに役立ついくつかの優れたツールもあります。

于 2013-10-17T17:14:23.820 に答える
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.

そこからゆっくりと拡張することから始めて、コードがどこで壊れているかを確認してください。

于 2013-03-12T15:04:32.307 に答える