2017-07-13 68 views
0

我有一套类,我想序列化到/从JSON和MongoDB数据库。我看到要做的最有效的方法是编写方法来序列化为字典,然后使用内置方法来存取数据。 (Q1:这个结论实际上是否有效,或者是否有更好的方法?有没有办法通过自检来获取类构造函数参数?

所以,要将我的类的实例导出为字典,我可以使用self。 字典。在我的情况下,这些类是嵌套的,所以它必须是递归的,很好。现在我想读回来......但现在我被卡住了,如果我的类有一个不平凡的构造函数。试想一下:

class MyClass(object): 
    def __init__(self, name, value=None): 
     self.name = name 
     self._value = value 
    @property 
    def value(self): 
     return self._value 

a = MyClass('spam', 42) 
d = a.__dict__ #has {'name':'spam', '_value':42} 
#now how to unserialize? 
b = MyClass(**d) #nope, because '_value' is not a valid argument 
c = MyClass(); c.__dict__.update(d) #nope, can't construct 'empty' MyClass 

我不想写,忽略未知参数的构造函数,因为我不喜欢浪费时间想为什么一类是忽略了一些参数,发现有在名称中一个错字弄清楚。我不想删除所需的参数,因为这可能会导致其他地方出现问题。

那么,如何解决我为自己制造的这个混乱?

  • 如果有办法绕过类的构造函数,并创建一个空的 对象,可能的工作,但如果在__init__做任何有用的工作,我失去的。 (例如参数的类型/范围检查)。
  • 在我的情况下,这些类在构造后不会改变(它们定义了很多有用的方法,并且有一些缓存)。所以,如果我能从字典中提取构造函数的参数,我会做得很好。有没有办法做到这一点,不涉及重复所有的构造函数参数?
+0

你最好创建反序列化每种类型的工厂方法,这样的类型拥有怎样的实际控制构建对象。否则,你只是在外面,猜测黑盒子的类型是如何工作的,因为你试图填充正确的值。 - 想象一下,如果'value'属性返回'self._value * 2'代替。 – poke

+1

你打开这样的黑客:http://ideone.com/R9T2Nd? –

+0

@poke我不明白你评论的最后部分;只要属性/方法不会改变任何属性,为什么我会关心它们的序列化呢? – thegreatemu

回答

0

我不知道这只是一个微不足道的例子,但我看不到属性value(没有双关语意图)的价值。如果你直接从__init__分配值参数,我的意思是。在这种情况下,只需使用简单的属性即可解决您的问题。

但是,如果由于某种原因,你真正需要的属性只是剥夺关键中的破折号:

class MyClass(object): 
    Pdef __init__(self, name, value=None): 
     self.name = name 
     self._value = value 
    @property 
    def value(self): 
     return self._value 

a = MyClass('spam', 42) 
d = {k.strip('_'): v for k, v in a.__dict__.items()} 
b = MyClass(**d) 
+0

这里的值确实是一个微不足道的例子,尽管这个例子给出了一些有用的“只读”属性。主要观点是构造函数参数不能直接映射到具有相同名称的“公共”属性上。过滤下划线的诀窍可能对我所做的事很简单 – thegreatemu

相关问题