В рамках рабочего процесса для анализа данных я использовал dill
некоторые сложные структуры, содержащие данные (в numpy массивах), а также лямбда-функции. Я без проблем работал с этой базой. Моя кодовая база находится в Python 2, но я хочу обновить ее и преобразовать в Python 3.
Теперь, когда я попытался загрузить базу данных в Python 3, я обнаружил проблемы. На первый взгляд проблема была похожа на этот вопрос . Однако изменение кодировки "latin1"
не работает, и мне нужно было использовать кодировку "bytes"
. Тем не менее, когда я запускаю следующий код (CMIPprocs
является модульной частью моей кодовой базы), впереди еще больше проблем:
import dill as pickle
import sys
sys.path.insert(0,"/Users/m300556/CMIP5_fin/Scripts/CMIPprocs")
import CMIPprocs as cmip
with open("../CMIP5_fin/Outputs/CMIP5.dict","rb") as f:
h=pickle.load(f,encoding="bytes")
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-2-e04ea9af05f6> in <module>
1 with open("../CMIP5_fin/Outputs/CMIP5.dict","rb") as f:
----> 2 h=pickle.load(f,encoding="bytes")
~/miniconda3/envs/glamdring/lib/python3.8/site-packages/dill/_dill.py in load(file, ignore, **kwds)
268 def load(file, ignore=None, **kwds):
269 """unpickle an object from a file"""
--> 270 return Unpickler(file, ignore=ignore, **kwds).load()
271
272 def loads(str, ignore=None, **kwds):
~/miniconda3/envs/glamdring/lib/python3.8/site-packages/dill/_dill.py in load(self)
470
471 def load(self): #NOTE: if settings change, need to update attributes
--> 472 obj = StockUnpickler.load(self)
473 if type(obj).__module__ == getattr(_main_module, '__name__', '__main__'):
474 if not self._ignore:
~/miniconda3/envs/glamdring/lib/python3.8/site-packages/dill/_dill.py in _load_type(name)
575
576 def _load_type(name):
--> 577 return _reverse_typemap[name]
578
579 def _create_type(typeobj, *args):
KeyError: b'CodeType'
Ошибка ключа b'CodeType'
сообщает мне, что кодировка "bytes"
меняет кое-что, связанное с этим вопросом . Уровень этого решения выходит за рамки моих знаний о Python, и я попробовал наивную модификацию решения, только чтобы закончиться другой ошибкой:
import dill as pickle
pickle._dill._reverse_typemap[b'CodeType']=type
import sys
sys.path.insert(0,"/Users/m300556/CMIP5_fin/Scripts/CMIPprocs")
import CMIPprocs as cmip
with open("../CMIP5_fin/Outputs/CMIP5.dict","rb") as f:
h=pickle.load(f,encoding="bytes")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-e04ea9af05f6> in <module>
1 with open("../CMIP5_fin/Outputs/CMIP5.dict","rb") as f:
----> 2 h=pickle.load(f,encoding="bytes")
~/miniconda3/envs/glamdring/lib/python3.8/site-packages/dill/_dill.py in load(file, ignore, **kwds)
268 def load(file, ignore=None, **kwds):
269 """unpickle an object from a file"""
--> 270 return Unpickler(file, ignore=ignore, **kwds).load()
271
272 def loads(str, ignore=None, **kwds):
~/miniconda3/envs/glamdring/lib/python3.8/site-packages/dill/_dill.py in load(self)
470
471 def load(self): #NOTE: if settings change, need to update attributes
--> 472 obj = StockUnpickler.load(self)
473 if type(obj).__module__ == getattr(_main_module, '__name__', '__main__'):
474 if not self._ignore:
TypeError: type() takes 1 or 3 arguments
Обновить
Я обнаружил, что установив
import dill as pickle
pickle._dill._reverse_typemap[b'CodeType']=pickle._dill._reverse_typemap['CodeType']
Теперь сообщение TypeError: an integer is required (got type bytes)
. Этот факт побудил меня поискать дополнительную информацию о том, что такое CodeType
, и обнаружил, что конструктор в Python 3.8 (версия, которую я использую) имеет дополнительный целочисленный аргумент (см. this ). Таким образом, основная проблема, я подозреваю, не в кодировке, а в конструкторе CodeType
. Я не знаю, как это решить. Пожалуйста, я очень прошу вашей помощи.
Обновление 2
Открыв исходный pickle в Python 2 и удалив некоторые лямбда-функции, которые у меня были, и снова засолить его , Я могу загрузить его в Python 3. Однако это не желаемый способ действия. Это подтверждает, что проблема именно в том, о чем я подозревал при первом обновлении.