Недавно меня попросили сделать так, чтобы «наша библиотека C ++ работала в облаке».
По сути, библиотека требует большого количества компьютеров (расчет цены), так что это имело бы смысл.
Я создал SWIG-интерфейс для создания версии на Python, чтобы использовать MapReduce с MRJob.
Я хотел сериализовать объекты в файле и, используя маппер, десериализовать и рассчитать цену.
Например:
class MRTest(MRJob):
def mapper(self,key,value):
obj = dill.loads(value)
yield (key, obj.price())
Но теперь я зашел в тупик, так как кажется, что укроп не может справиться с расширением SWIG:
PicklingError: Can't pickle <class 'SwigPyObject'>: it's not found as builtins.SwigPyObject
Есть ли способ сделать эту работу правильно?
Я dill
автор. Правильно, dill
не может засолить объекты C ++. Когда ты видишь it's not found as builtin.
some_object… это почти всегда означает, что вы пытаетесь засолить какой-то объект это не написано на python, но использует python для привязки к C / C ++ (то есть тип расширения). У вас нет надежды на непосредственное извлечение таких объектов с помощью сериализатора Python.
Однако, поскольку вы заинтересованы в выборе подкласса типа расширения, вы можете это сделать. Все, что вам нужно сделать, это дать вашему объекту соответствующее состояние, которое вы хотите сохранить в качестве атрибута или атрибутов экземпляра, и предоставить __reduce__
способ рассказать dill
(или же pickle
) как сохранить состояние вашего объекта. Этот метод — то, как python имеет дело с сериализацией типов расширения. Увидеть:
https://docs.python.org/2/library/pickle.html#pickling-and-unpickling-extension-types
Вероятно, есть лучшие примеры, но вот по крайней мере один пример:
https://stackoverflow.com/a/19874769/4646678