Попытка отрендерить большой и (возможно, очень) неподдающийся обработке объект в файл для последующего использования.
Со стороны dill.dump(file)
претензий нет:
In [1]: import echonest.remix.audio as audio
In [2]: import dill
In [3]: audiofile = audio.LocalAudioFile("/Users/path/Track01.mp3")
en-ffmpeg -i "/Users/path/audio/Track01.mp3" -y -ac 2 -ar 44100 "/var/folders/X2/X2KGhecyG0aQhzRDohJqtU+++TI/-Tmp-/tmpWbonbH.wav"
Computed MD5 of file is b3820c166a014b7fb8abe15f42bbf26e
Probing for existing analysis
In [4]: with open('audio_object_dill.pkl', 'wb') as f:
...: dill.dump(audiofile, f)
...:
In [5]:
Но пытаюсь загрузить файл .pkl
:
In [1]: import dill
In [2]: with open('audio_object_dill.pkl', 'rb') as f:
...: audio_object = dill.load(f)
...:
Возвращает следующую ошибку:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-203b696a7d73> in <module>()
1 with open('audio_object_dill.pkl', 'rb') as f:
----> 2 audio_object = dill.load(f)
3
/Users/mikekilmer/Envs/GLITCH/lib/python2.7/site-packages/dill-0.2.2.dev-py2.7.egg/dill/dill.pyc in load(file)
185 pik = Unpickler(file)
186 pik._main_module = _main_module
--> 187 obj = pik.load()
188 if type(obj).__module__ == _main_module.__name__: # point obj class to main
189 try: obj.__class__ == getattr(pik._main_module, type(obj).__name__)
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.pyc in load(self)
856 while 1:
857 key = read(1)
--> 858 dispatch[key](self)
859 except _Stop, stopinst:
860 return stopinst.value
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.pyc in load_newobj(self)
1081 args = self.stack.pop()
1082 cls = self.stack[-1]
-> 1083 obj = cls.__new__(cls, *args)
1084 self.stack[-1] = obj
1085 dispatch[NEWOBJ] = load_newobj
TypeError: __new__() takes at least 2 arguments (1 given)
AudioObject намного сложнее (и больше), чем class object
, для которого выполняются вышеуказанные вызовы (из SO answer), и мне неясно, нужно ли мне отправлять второй аргумент через dill
, и если да, то каким будет этот аргумент или как определить, есть ли какой-либо подход к травлению пригодны для данного конкретного объекта.
Немного осмотрим сам объект:
In [4]: for k, v in vars(audiofile).items():
...: print k, v
...:
возвращает:
is_local False
defer False
numChannels 2
verbose True
endindex 13627008
analysis <echonest.remix.audio.AudioAnalysis object at 0x103c61bd0>
filename /Users/mikekilmer/Envs/GLITCH/glitcher/audio/Track01.mp3
convertedfile /var/folders/X2/X2KGhecyG0aQhzRDohJqtU+++TI/-Tmp-/tmp9ADD_Z.wav
sampleRate 44100
data [[0 0]
[0 0]
[0 0]
...,
[0 0]
[0 0]
[0 0]]
И audiofile.analysis
, кажется, содержит атрибут с именем audiofile.analysis.source
, который содержит (или явно указывает на) audiofile.analysis.source.analysis
cls.__new__(cls, *args)
- person MikeiLL   schedule 28.08.2014echonest
API, чтобы опробовать его в случае необходимости? В любом случае, есть несколько вещей, которые вы можете попытаться выяснить, что происходит. Во-первых, поскольку это класс, вы можете попробовать переключитьbyref
вdill.dumps
, чтобы переключить выделение класса по ссылке. Если это не сработает, попробуйте включитьdill.detect.trace(True)
, чтобы увидеть внутренние контрольные точки в (де)сериализации. Вы также можете просмотреть методы вdill.detect
, такие какbadobjects
, которые могут помочь диагностировать, что происходит. Похоже на несоответствие__getstate__
и__setstate__
, что было бы странно. - person Mike McKerns   schedule 28.08.2014with open('audio_object_dill.pkl', 'wb') as f:
byref было установлено таким образом,dill.dump(audiofile, f, byref=True)
сFalse
было бы значением по умолчанию, верно?dill.load
результаты совпадают. Введеноdill.detect.trace(True)
доdill.dump
результатов вызова: pastebin.com/V0fA7aVJ. Наконец,dill.detect.badobjects(audiofile)
возвращает<echonest.remix.audio.LocalAudioFile at 0x103ebc710>
. Хм. - person MikeiLL   schedule 28.08.2014dill.detect.children(audiofile, echonest.remix.audio.LocalAudioFile)
выдает, что имя 'ehonest' не определено - на самом деле просто нужно было вызвать его с помощью модуля переменной, который был импортирован с помощью:dill.detect.children(audiofile, audio.LocalAudioFile)
, что дает наш старый друг[<echonest.remix.audio.LocalAudioFile at 0x103ebc710>]
- person MikeiLL   schedule 28.08.2014trace
у вас в pastebin. Да, это все материалы для чтения наdill
, к сожалению. Кстати, вы должны попробоватьbadobjects(audiofile, depth=1)
-- это позволит вам копаться в каждом объекте, даже в том, что не удалось. Также проверьте это как пример того, что может сделать обнаружение укропа. stackoverflow .com/questions/10082241/ stackoverflow.com/questions/25241139/ - person Mike McKerns   schedule 29.08.2014f(self, obj) # Call unbound method with explicit self
в методе picklesave
. - person MikeiLL   schedule 29.08.2014dump
напрямую), и может быть поэтому кажется, чтоload
ожидает чего-то другого. - person Mike McKerns   schedule 30.08.2014