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