Home > Software design >  Python equivalent of Go Struct and Unmarshal
Python equivalent of Go Struct and Unmarshal

Time:10-03

So I'm working with some JSON data in Python. Its basically a wrapper for an API though I want to have dot access to my values like data.size, I've done a bit of research but I couldn't find the desired results.

I was using json.loads to parse my data so I tried object hooks but that isn't what I want.

Here's an example Go code that I want to replicate.

type dat struct {
    ResponseTime int
    Body body
}

type body struct {
    Day int
    Month int
    Year int
}

var h dat
// e here is my json
data = json.Unmarshal(e, &h)

My results in Python were similar but they were instances of the same class. My aim is to be able to parse nested dicts and I want to be able to define which dict assigns to which object... not sure if u understand but theres the Go code for you.

CodePudding user response:

Using dataclass and dacite

from dataclasses import dataclass
import dacite

@dataclass
class Body:
    day:int
    month:int
    year:int

@dataclass
class Dat:
    response_time: int
    body: Body
data = {'response_time':12, 'body':{'day':1,'month':2,'year':3}}

dat: Dat = dacite.from_dict(Dat,data)
print(dat)

output

Dat(response_time=12, body=Body(day=1, month=2, year=3))

CodePudding user response:

Using pymarshaler (Which is close to to golang approach)

import json

from pymarshaler.marshal import Marshal


class Body:
    def __init__(self, day: int, month: int, year: int):
        self.day = day
        self.month = month
        self.year = year

class Dat:
    def __init__(self, response_time: int, body: Body):
        self.response_time = response_time
        self.body = body

marshal = Marshal()

dat_test = Dat(3, Body(1, 2, 3))
dat_json = marshal.marshal(dat_test)
print(dat_json)

result = marshal.unmarshal(Dat, json.loads(dat_json))
print(result.response_time)

see https://pythonawesome.com/marshall-python-objects-to-and-from-json/

CodePudding user response:

So turns out it wasn't that hard, I just didn't want to try. For anyone with the same problem here's the code.

class Typs(object):
    def __init__(self):
        self.type = int
        self.breed = str


class Deets(object):
    def __init__(self):
        self.color = str
        self.type = Typs()


class Base(object):
    def __init__(self):
        self.name = str
        self.details = Deets()


d = {
    "name": "Hello",
    "details": {"color": "black", "type": {"type": 2, "breed": "Normal"}},
}

h = Base()


def unmarshal(d, o):
    for k, v in d.items():
        if hasattr(o, k):
            if isinstance(v, dict):
                unmarshal(v, getattr(o, k))
            else:
                setattr(o, k, v)

    return o


x = unmarshal(d, h)
  • Related