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

问题描述 投票:1回答:1

我正在尝试创建一个区块链,需要一个函数将我的块放入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())只是将我的对象类型命名为“块”,但实际上并没有对其应用任何内容以使其成为对象。我可以调用element.attribute,但不能再次调用element.to_json(),因为错误消息是AttributeError: 'Block' object has no attribute 'to_json'。我曾考虑过每手对其进行解码,但是由于我不能使用多个构造函数,所以这似乎不是一个好主意。如果有人可以帮助我,那就太好了

python json object constructor namedtuple
1个回答
0
投票

似乎namedtuple('Block', jsondict.keys())(*jsondict.values()) 只是将我的对象类型命名为“块”,但实际上并没有对其应用任何东西以使其成为对象。

一切都是对象。 namedtuple是工厂函数,它创建一个支持命名属性访问的[tuple]的子类,但

它仍然是tuple。我不确定为什么要

expect将其作为您定义的自定义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})

而且继承的作用更好。这些类方法通常称为

替代构造函数

© www.soinside.com 2019 - 2024. All rights reserved.