不同模块中的 Pickling 和 Unpickling
Pickling and Unpickling in different modules
我知道许多其他问题 () 已经涵盖了这一点,但我看不出他们的解决方案如何适用于我的情况。
这是我的项目结构(尽可能最小):
classify-updater/
├── main.py
└── updater
├── __init__.py
└── updater.py
classify
└── main.py
在classify-updater/main.py
中:
import sys
from sklearn.feature_extraction.text import CountVectorizer
from updater.updater import Updater
def main(argv):
vectorizer = CountVectorizer(stop_words='english')
updater = Updater(vectorizer)
updater.update()
if __name__ == "__main__":
main(sys.argv)
在classify-updater/updater/updater.py
中:
import dill
class Updater:
def __init__(vectorizer):
vectorizer.preprocessor = lambda doc: doc.text.encode('ascii', 'ignore')
self.vectorizer = vectorizer
def update(self):
pickled_vectorizer = dill.dumps(self.vectorizer)
# Save to Google Cloud Storage
在classify/main.py
import dill
import sys
def main(argv):
# Load from Google Cloud Storage
vectorizer = dill.loads(vectorizer_blob)
if __name__ == "__main__":
main(sys.argv)
这导致 ImportError
。
Traceback (most recent call last):
File "classify.py", line 102, in <module>
app.main(sys.argv)
File "classify.py", line 50, in main
vectorizer = self.fetch_vectorizer()
File "classify.py", line 86, in fetch_vectorizer
vectorizer = dill.loads(vectorizer_blob.download_as_string())
File "/usr/local/lib/python2.7/site-packages/dill/dill.py", line 299, in loads
return load(file)
File "/usr/local/lib/python2.7/site-packages/dill/dill.py", line 288, in load
obj = pik.load()
File "/usr/local/Cellar/python/2.7.13_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 864, in load
dispatch[key](self)
File "/usr/local/Cellar/python/2.7.13_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1096, in load_global
klass = self.find_class(module, name)
File "/usr/local/lib/python2.7/site-packages/dill/dill.py", line 445, in find_class
return StockUnpickler.find_class(self, module, name)
File "/usr/local/Cellar/python/2.7.13_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1130, in find_class
__import__(module)
ImportError: No module named updater.updater
在其他地方已经解释过 pickle 需要 class 定义来加载对象,但是我看不到更新模块的引用来自哪里,因为我只是 pickle 的一个实例矢量器。
我已经大大简化了这个例子。就我们的代码库而言,这两个包相距甚远。将一个模块导入另一个模块可能不可行。有什么办法可以解决这个问题吗?
这里的问题是 lambda(匿名函数)。
像 Vectorizer 这样的自包含对象是完全可以 pickle 的。但是,该示例中使用的预处理函数的作用域是更新程序 class,因此需要更新程序 class 来解封。
与其使用预处理器函数,不如自己预处理数据并将其传入以适应向量化器。这将消除在 unpickling 时对更新程序 class 的需要。
我知道许多其他问题 (
这是我的项目结构(尽可能最小):
classify-updater/
├── main.py
└── updater
├── __init__.py
└── updater.py
classify
└── main.py
在classify-updater/main.py
中:
import sys
from sklearn.feature_extraction.text import CountVectorizer
from updater.updater import Updater
def main(argv):
vectorizer = CountVectorizer(stop_words='english')
updater = Updater(vectorizer)
updater.update()
if __name__ == "__main__":
main(sys.argv)
在classify-updater/updater/updater.py
中:
import dill
class Updater:
def __init__(vectorizer):
vectorizer.preprocessor = lambda doc: doc.text.encode('ascii', 'ignore')
self.vectorizer = vectorizer
def update(self):
pickled_vectorizer = dill.dumps(self.vectorizer)
# Save to Google Cloud Storage
在classify/main.py
import dill
import sys
def main(argv):
# Load from Google Cloud Storage
vectorizer = dill.loads(vectorizer_blob)
if __name__ == "__main__":
main(sys.argv)
这导致 ImportError
。
Traceback (most recent call last):
File "classify.py", line 102, in <module>
app.main(sys.argv)
File "classify.py", line 50, in main
vectorizer = self.fetch_vectorizer()
File "classify.py", line 86, in fetch_vectorizer
vectorizer = dill.loads(vectorizer_blob.download_as_string())
File "/usr/local/lib/python2.7/site-packages/dill/dill.py", line 299, in loads
return load(file)
File "/usr/local/lib/python2.7/site-packages/dill/dill.py", line 288, in load
obj = pik.load()
File "/usr/local/Cellar/python/2.7.13_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 864, in load
dispatch[key](self)
File "/usr/local/Cellar/python/2.7.13_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1096, in load_global
klass = self.find_class(module, name)
File "/usr/local/lib/python2.7/site-packages/dill/dill.py", line 445, in find_class
return StockUnpickler.find_class(self, module, name)
File "/usr/local/Cellar/python/2.7.13_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1130, in find_class
__import__(module)
ImportError: No module named updater.updater
在其他地方已经解释过 pickle 需要 class 定义来加载对象,但是我看不到更新模块的引用来自哪里,因为我只是 pickle 的一个实例矢量器。
我已经大大简化了这个例子。就我们的代码库而言,这两个包相距甚远。将一个模块导入另一个模块可能不可行。有什么办法可以解决这个问题吗?
这里的问题是 lambda(匿名函数)。
像 Vectorizer 这样的自包含对象是完全可以 pickle 的。但是,该示例中使用的预处理函数的作用域是更新程序 class,因此需要更新程序 class 来解封。
与其使用预处理器函数,不如自己预处理数据并将其传入以适应向量化器。这将消除在 unpickling 时对更新程序 class 的需要。