如何使用复杂的构造函数从 python 中的 json 创建对象?



我正在尝试创建一个区块链,需要一个函数将我的块转换为json格式并能够再次创建对象。这似乎很困难,因为我的构造函数没有将所有属性作为参数。我的构造函数如下所示:

class Block:
id = 0
def __init__(self, transaction, prevhash):
self.transactions  = []         
self.transactions.append(transaction)
self.prevhash = prevhash        
self.timestamp = time.time()    
self.id = Block.id          
Block.id = Block.id + 1     

我对它们进行以下编码(似乎工作得很好(:

def to_json(self):
return json.dumps(self, indent=4, cls=BlockEncoder)
class BlockEncoder(JSONEncoder):
def default(self, o):
return o.__dict__

它为我创建了该输出(仅举一个例子(:

{
"transactions": [
{
"ipfshash": 1,
"title": null,
"length": null,
"id": 0
},
{
"ipfshash": 3,
"title": null,
"length": null,
"id": 2
}
],
"prevhash": 10,
"timestamp": 1591350715.1794589,
"id": 0
}

我现在试图再次将其放入对象中是(我需要像对象这样的生成器来调用该函数,但它有效。仍在试图弄清楚如何使那个静态:D(

def from_json(self, jsondict):
return json.loads(jsondict, object_hook=custom_block_decoder)
def custom_block_decoder(jsondict):
return namedtuple('Block', jsondict.keys())(*jsondict.values())

因此,如果我使用某个元素并打印它,它将不会使用我定义的__str__函数,我也不能调用我的 Block 类的任何其他函数。似乎namedtuple('Block', jsondict.keys())(*jsondict.values())只是将我的对象类型命名为"Block",但并没有真正对其应用任何内容以使其成为对象。我可以调用element.attribute,但不能再次调用element.to_json((,因为错误消息AttributeError: 'Block' object has no attribute 'to_json'。我考虑过按手解码它,但由于我不能使用多个构造函数,这似乎不是一个好主意。如果有人能帮助我,那就太好了

你为什么要用namedtuple

看来namedtuple('Block', jsondict.keys())(*jsondict.values())只是将我的对象类型命名为"Block",但并没有真正对其应用任何内容以使其成为对象。

一切都是物体。namedtuple是一个工厂函数,用于创建支持命名属性访问的tuple子类,但它仍然是一个tuple。我不确定为什么您希望它是您定义的自定义Block类的实例。在这里使用它没有多大意义。

在任何情况下,您都必须自己编写反序列化例程。一般来说,这看起来像

class Foo:
def __init__(self, bar):
self.bar = bar
self.baz = 42
def frobnicate(self):
baz = self.baz
self.baz = self.baz ** 2 // 4
@classmethod
def from_dict(cls, dict_foo):
foo = cls.__new__(cls) # just object.__new__
# here is where you have to implement the logic yourself to rebuild your object. 
# hopefully it doesn't get too complex
foo.__dict__.update(dict_foo)
return foo

注意,使用类方法是习惯性的,那么您可以使用

Foo.from_dict({'bar': 8, 'baz': 42})

而且它在继承方面玩得更好一些。这些类型的类方法通常称为替代构造函数

最新更新