为什么 igraph.Graph 的方法既不是 "pickle-able" 也不是 "dill-able"?

Why are methods of igraph.Graph neither "pickle-able" nor "dill-able"?

为什么不能用 pickle 或 dill 序列化 igraph.Graph 的方法?这两种方法都会产生 PicklingError.

示例:

import igraph, dill, pickle

pickle.dumps(igraph.Graph.degree)
dill.dumps(igraph.Graph.degree)

此处,dumps 的两次调用均以异常结束:

PicklingError                             Traceback (most recent call last)
...
PicklingError: Can't pickle <class 'igraph.Graph'>: it's not the same object as igraph.Graph

创建如下所示的包装函数是一种可能的解决方法,但这并不能解释最初的问题。

def degree_wrapper(graph, *args, **kwargs):
    return graph.degree(*args, **kwargs)

还有其他方法可以使莳萝适用于这些情况吗?

仅供参考: python-igraph==0.7.1.post6;莳萝==0.2.5; Python 3.4.3+(默认,2015 年 10 月 14 日,16:03:50)[GCC 5.2.1 20151010]; Ubuntu15.10

我认为这不是 igraph 特有的; pickle 模块的文档列出了可以 pickle 的对象:

The following types can be pickled:

  • None, True, and False
  • integers, long integers, floating point numbers, complex numbers
  • normal and Unicode strings
  • tuples, lists, sets, and dictionaries containing only picklable objects
  • functions defined at the top level of a module
  • built-in functions defined at the top level of a module
  • classes that are defined at the top level of a module
  • instances of such classes whose __dict__ or the result of calling __getstate__() is picklable (see section The pickle protocol for details).

Graph class 的 degree 方法不符合上述任何类别。您的函数可以,因为它(大概)是在模块的顶层定义的。

至于dill,我不知道,但由于它是建立在pickle上的,可以假设同样的限制也适用于dill