【发布时间】:2011-06-06 13:29:54
【问题描述】:
我有一个通常存储腌制类类型的系统。
我希望能够以相同的方式保存动态参数化的类,但我不能,因为我在尝试腌制一个未全局找到的类(未在简单代码中定义)时收到 PicklingError。
我的问题可以建模为以下示例代码:
class Base(object):
def m(self):
return self.__class__.PARAM
def make_parameterized(param_value):
class AutoSubClass(Base):
PARAM = param_value
return AutoSubClass
cls = make_parameterized(input("param value?"))
当我尝试腌制课程时,我收到以下错误:
# pickle.PicklingError: Can't pickle <class '__main__.AutoSubClass'>: it's not found as __main__.AutoSubClass
import pickle
print pickle.dumps(cls)
我正在寻找一些方法来将 Base 声明为 ParameterizableBaseClass,它应该定义所需的参数(上面示例中的 PARAM)。动态参数化子类(上面的cls)应该可以通过保存“ParameterizableBaseClass”类型和不同的参数值(上面的动态param_value)来挑选。
我确信在许多情况下,这可以完全避免......如果我真的(真的)必须这样做,我也可以在我的代码中避免这种情况。我在某个时候玩过__metaclass__、copyreg 甚至__builtin__.issubclass(不要问),但无法破解这个。
如果我不问:如何以相对干净的方式实现这一点,我觉得我不会忠于蟒蛇精神?
【问题讨论】:
-
以相对干净的方式?我认为“干净”的任何合理定义都不可能。您为什么要尝试腌制其类在运行时生成的对象?实际用例是什么?你将如何解开那些类不存在的东西?
-
我也不明白这个用例。为什么你不能在初始化后只返回一个带有该参数的类的实例作为属性。另一条评论,您还应该避免使用 python 魔法,即
self.__class__.PARAM。我认为你过于复杂了。 -
这可能是过于复杂的情况(在这种情况下,问题可能仍然存在,即使不考虑我的情况)。我的例子可能看起来很愚蠢——这只是一个例子。我的真实系统将类类型与创建参数一起腌制,并在并行处理场景中的进程之间传递它们。除了使用大约 20 个不同的类,每个类都有特定的代码,我还有一些“只需选择你的参数”类。我希望能够动态地对它们进行子类化,而无需更改(并可能重新加载)代码,并使它们可腌制。 HTH。
-
@Lennart:“你要如何解开那些类不存在的东西?” - 通过在 unpickle 时间创建课程! :-) - 请参阅下面的答案。
-
@jsbueno:我不得不说,在那种情况下,感觉就像整个动态类创建可以被跳过,它仍然可以工作。你知道名字,参数是动态的吗?好吧,您不需要为此创建一个类...
标签: python class dynamic factory pickle