酸洗动态生成的类?

rec*_*ner 28 python metaprogramming class dynamic

我正在使用type()动态生成最终将被pickle的类.问题是un-pickling进程需要类的定义才能重新构造被pickle的对象.

这就是我被困住的地方.我不知道如何以某种方式 unpickler 提供一种从动态生成的类生成实例的方法.

任何提示赞赏.

谢谢!

这是一个问题的例子:

    >>> class Foo(object):
    ...     pass
    >>> g=type('Goo',(Foo,),{'run':lambda self,x: 2*x } )()
    >>> cPickle.dumps(g)

    PicklingError: Can't pickle <class '__main__.Goo'>: attribute lookup __main__.Goo failed
Run Code Online (Sandbox Code Playgroud)

这显然是有效的,但仅限于从可发现的基类(具有可查找的模块定义)创建的动态类:

import cPickle

class Foo(object): pass

def dynamic(): return type('Goo',(Foo,),{'run':lambda self,x: 2*x } )()

g=type('Goo',(Foo,),{'run':lambda self,x: 2*x , '__reduce__': lambda self: (dynamic,tuple()) } )()

gg=cPickle.loads ( cPickle.dumps(g) )
print gg.run(10)
Run Code Online (Sandbox Code Playgroud)

Sha*_*mas 15

当Pickler遇到一个它一无所知的类型的对象时,它会查找reduce方法.使用类型构建自定义类时定义此方法应解决酸洗问题.

如果你提供初始args,那么你可能需要定义一个getnewargs方法

  • [这个答案](http://stackoverflow.com/a/11493777/456550) 有一个如何使用 `__reduce__` 进行酸洗的示例。 (2认同)

Bre*_*els 5

您可以为动态生成的类分配一个全局名称,以使其可挑选。

>>> class Foo(object):
...     pass
>>> class_name = 'Goo'
>>> my_class = type(class_name, (Foo, ), {'run': lambda self, x: 2*x })
>>> globals()[class_name] = my_class
>>> g = my_class()
>>> pickle.dumps(g)
Run Code Online (Sandbox Code Playgroud)

当然,您需要确保类的名称是唯一的。