Pickle используется модулем multiprocessing
для связи между различными частями, и в Руководстве по программированию объясняется, что вы должны убедиться, что все ваши данные, которые вы передаете между процессами, должны быть совместимы с травлением:
Возможность выбора : убедитесь, что аргументы методов прокси можно выбрать.
Вы используете данные, которые нельзя выбрать.
В частности, что происходит неправильно, так это то, что класс cv2.Boost
не совсем говорит правду о том, как вы можете создать больше копий класса.pickle
хранит ссылки на классы и функции, а не на их определения, потому что это намного эффективнее.Это означает, что экземплярам нужно хранить данные только для этого экземпляра, а не все иерархии классов и определения методов.
Для этого pickle
принимает модуль, в котором определен класс или функция.и имя объекта, и вместе это ссылка на класс или функцию.Затем перепроверяет , что он может использовать это имя для повторной загрузки того же класса или функции.
Эта проверка работоспособности не удалась для класса cv2.Boost
.У вас есть экземпляры класса с именем Boost
, который утверждает, что он поступил из модуля cv2
, но когда pickle
затем переходит к модулю cv2
и ищет атрибут Boost
того модуля, который он обнаружил другой объект .Это означает, что ваши данные не могут быть выбраны.
Есть способы исправить это;вам нужно научить модуль pickle
использовать другую функцию для повторной загрузки тех же данных, используя функцию copyreg.pickle()
;если такая регистрация существует для класса cv2.Boost
, то pickle
не выполнит вышеуказанную проверку:
import copyreg
import cv2
def _pickle_boost(boost):
return cv2.Boost, (
boost.trainData,
boost.tflag,
boost.responses,
boost.varIdx,
boost.sampleIdx,
boost.varType,
boost.missingDataMask,
boost.paramsd,
)
copyreg.pickle(cv2.Boost().__class__, _pickle_boost)
ПРЕДУПРЕЖДЕНИЕ : на самом деле я этого не делалпроверьте, сработает ли вышеуказанное, потому что у меня не установлена локальная версия 2.4.x cv2
;Я просто сослался на cv2.Boost()
документацию , чтобы догадаться, какими атрибутами будет обладать такой класс.Вы, вероятно, должны будете настроить это.Идея состоит в том, что для типа cv2.Boost().__class__
вызывается функция _pickle_boost()
, возвращающая вызываемый объект (cv2.Boost
) для создания нового экземпляра и аргументы, которые вы хотите передать этому вызываемому элементу.
Если какое-либо из приведенных выше значений сами по себе являются более cv2
типами, которые представляют такую же проблему, то вам нужно зарегистрировать больше функций.