Python3 C-libs:如何序列化依赖于 C .dll 的 class 以便在裸实例中使用?
Python3 C-libs: How do I serialize a class that depends on C .dlls for use in a bare instance?
例如:
// file foo
def my_func():
print("foo!")
// file bar
class Bar:
def __init__(self):
pass
def hello():
import foo.my_func
my_func()
import dill
dill.dump(Bar(), open("bar.dpkl",mode='wb+'))
$: python3 -m venv foobar
$: source activate foobar/bin/activate
(foobar) $: python3
>>> import dill
>>> obj = dill.load(open("bar.dpkl",mode='rb')) # just fine
>>> obj.hello()
foo!
但是,假设我做了一个转折:
class Bar:
def __init__(self):
import numpy
现在,
>>> obj = dll.load(open("bar.dpkl",mode='rb'))
ModuleNotFoundError: No module named 'numpy'
链接的 C
-二进制文件似乎没有捆绑在 pickle
文件中。然而,如果代码是真正的原生 python
代码,dill
输出的 pickle
文件本质上是一个动态存档。
有什么方法可以扩展这种动态存档行为以包括 numpy
等库?或者必须始终将这些 C
+ python
-shell 库安装在执行 python
环境中?
基本上,我想我要的是 jar
的 pythonic 版本,它可以直接从 python
代码生成:这可能吗?或者是我正在寻找的 jar
具有必要依赖项的容器?
可能的解决方案:
import dill
class Bar:
def __init__(self, foo):
self.basename = foo.name
self.deps = deepcopy(foo.deps)
self.foo = '-'.join([self.basename,'foo'])
self.bar = '-'.join([self.basename,'bar'])
def install(self):
import pip
pip.main(["install"] + self.deps) # this method will be deprecated soon
def load(self):
self.install()
foo = dill.load(open(self.foo,'rb'))
return foo
def store_self():
with open(self.bar + '.dpkl','wb+') as out:
dill.dump(out,self)
@classmethod
def store(cls, foo):
bar = cls(foo)
bar.store_self()
bar.install()
with open(self.foo + '.dpkl','wb+') as out:
dill.dump(out,foo)
class Foo:
def __init__(self,name,*arg,**kwargs):
self.name = name
self.deps = [ "numpy" ]
def hello():
import numpy
print("foo")
...
foo = Foo("Hello! I'm a foo!")
Bar.store(foo)
$: python3 -m venv venv-foo
$: source venv-foo/bin/activate
$: python3 -m pip install dill
>>> import dill
>>> bar = dill.load(open('bar.dpkl','rb'))
>>> foo = bar.load()
>>> foo.hello()
Hello! I am a foo!
不保证可复制粘贴性,但要点就在那里。可能需要稍微修改一下才能使 Bar.dpkl
正常工作。它也对 python3
的版本敏感。
再做一些工作,原生 pickle 可能可以用来存储 Bar
,然后可以用来安装 dill
。
例如:
// file foo
def my_func():
print("foo!")
// file bar
class Bar:
def __init__(self):
pass
def hello():
import foo.my_func
my_func()
import dill
dill.dump(Bar(), open("bar.dpkl",mode='wb+'))
$: python3 -m venv foobar
$: source activate foobar/bin/activate
(foobar) $: python3
>>> import dill
>>> obj = dill.load(open("bar.dpkl",mode='rb')) # just fine
>>> obj.hello()
foo!
但是,假设我做了一个转折:
class Bar:
def __init__(self):
import numpy
现在,
>>> obj = dll.load(open("bar.dpkl",mode='rb'))
ModuleNotFoundError: No module named 'numpy'
链接的 C
-二进制文件似乎没有捆绑在 pickle
文件中。然而,如果代码是真正的原生 python
代码,dill
输出的 pickle
文件本质上是一个动态存档。
有什么方法可以扩展这种动态存档行为以包括 numpy
等库?或者必须始终将这些 C
+ python
-shell 库安装在执行 python
环境中?
基本上,我想我要的是 jar
的 pythonic 版本,它可以直接从 python
代码生成:这可能吗?或者是我正在寻找的 jar
具有必要依赖项的容器?
可能的解决方案:
import dill
class Bar:
def __init__(self, foo):
self.basename = foo.name
self.deps = deepcopy(foo.deps)
self.foo = '-'.join([self.basename,'foo'])
self.bar = '-'.join([self.basename,'bar'])
def install(self):
import pip
pip.main(["install"] + self.deps) # this method will be deprecated soon
def load(self):
self.install()
foo = dill.load(open(self.foo,'rb'))
return foo
def store_self():
with open(self.bar + '.dpkl','wb+') as out:
dill.dump(out,self)
@classmethod
def store(cls, foo):
bar = cls(foo)
bar.store_self()
bar.install()
with open(self.foo + '.dpkl','wb+') as out:
dill.dump(out,foo)
class Foo:
def __init__(self,name,*arg,**kwargs):
self.name = name
self.deps = [ "numpy" ]
def hello():
import numpy
print("foo")
...
foo = Foo("Hello! I'm a foo!")
Bar.store(foo)
$: python3 -m venv venv-foo
$: source venv-foo/bin/activate
$: python3 -m pip install dill
>>> import dill
>>> bar = dill.load(open('bar.dpkl','rb'))
>>> foo = bar.load()
>>> foo.hello()
Hello! I am a foo!
不保证可复制粘贴性,但要点就在那里。可能需要稍微修改一下才能使 Bar.dpkl
正常工作。它也对 python3
的版本敏感。
再做一些工作,原生 pickle 可能可以用来存储 Bar
,然后可以用来安装 dill
。