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

2024-09-28 05:22:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个区块链,需要一个函数将我的区块转换为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__函数,也不能调用块类的任何其他函数。看起来namedtuple('Block', jsondict.keys())(*jsondict.values())只是将我的对象类型命名为“Block”,但并没有真正应用任何东西使其成为对象。我可以调用element.attribute,但不能再次调用element.to_json(),因为错误消息是AttributeError: 'Block' object has no attribute 'to_json'。我曾想过每只手解码它,但因为我不能使用多个构造函数,这似乎不是一个好主意。如果有人能帮我就好了


Tags: to对象函数selfidjsonreturndef
1条回答
网友
1楼 · 发布于 2024-09-28 05:22:53

为什么要使用namedtuple

It seems that namedtuple('Block', jsondict.keys())(*jsondict.values()) just names my object type "Block" but does not really apply anything to it to make it an object.

一切都是对象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

注意,使用classmethod是一种习惯,然后您可以使用

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

它在继承方面发挥得更好。这些类方法通常被称为替代构造函数

相关问题 更多 >

    热门问题