#!/usr/bin/env python # coding: utf-8 # In[64]: from dataclasses import dataclass from dataclasses import field from struct import Struct from math import sqrt from collections import namedtuple import sys # In[2]: @dataclass class vecf: x: float y: float z: float packer: Struct = field(init=False, repr=False, default=Struct( "fff" )) def normalize(self): return sqrt(self.x*self.x + self.y*self.y + self.z*self.z) def pack(self): return self.packer.pack(*self.to_list()) def unpack(self, pkt): return self.packer.unpack(pkt) def to_list(self): ret = [] for a in self.__dict__.values(): if isinstance(a,float) or isinstance(a,int): ret.append(a) else: for i in a.to_list(): ret.append(i) return ret # In[3]: @dataclass class imu: id: int # something accel: vecf gyro: vecf mag: vecf pressure: float temperature: float timestamp: int packer: Struct = field(init=False, repr=False, default=Struct( "BfffffffffffI" )) def pack(self): data = self.to_list() print(data) return self.packer.pack(*data) def unpack(self, pkt): return self.packer.unpack(pkt) def to_list(self): ret = [] for a in self.__dict__.values(): if isinstance(a,float) or isinstance(a,int): ret.append(a) else: for i in a.to_list(): ret.append(i) return ret # In[4]: v = vecf(1,2,3) print(v) import dataclasses f = dataclasses.fields(v)[0] l = [] for a in v.__dict__.values(): if isinstance(a,float) or isinstance(a,int): l.append(a) else: for i in a.to_list(): l.append(i) l # f.values() # for ff in f: # print(ff) # In[5]: v.to_list() # In[6]: pkt = v.pack() print(pkt) # In[7]: m = v.unpack(pkt) print(v) # In[8]: i = imu(1,vecf(1,2,3),vecf(4,5,6),vecf(7,8,9),1,2,3) print(i) # In[9]: pkt = i.pack() print(pkt) # In[ ]: # In[ ]: # In[101]: class Base: def flatten(self, data): """ (0, (1, 2, 3), (4, 5, 6)) -> (0, 1, 2, 3, 4, 5, 6) """ if isinstance(data, tuple): for x in data: yield from self.flatten(x) else: yield data def serialize(self): return tuple(self.flatten(dataclasses.astuple(self))) @dataclass(frozen=True) class vec_t(Base): x: float y: float z: float def __yivo__(self): return ("fff", 12, vec_t) # (struct format, number bytes) @dataclass(frozen=True) class twist_t(Base): linear: vec_t angular: vec_t def __yivo__(self): return ("3f3f", 120, twist_t) # (struct format, number bytes) # def __init__(self,lx,ly,lz,ax,ay,az): # object.__setattr__(self, "linear", vec_t(lx,ly,lz)) # object.__setattr__(self, "angular", vec_t(ax,ay,az)) def fmt(a): return a.__yivo__()[0] def sizeof(a): return a.__yivo__()[1] def cls(a): return a.__yivo__()[2] # In[102]: t=twist_t(vec_t(0,1,2),vec_t(3,4,5)) t # In[103]: t.serialize() # In[104]: dataclasses.astuple(t) # In[105]: t2=twist_t(vec_t(0,1,2),vec_t(3,4,5)) t == t2 # In[106]: fmt(t) # In[107]: sizeof(t) # In[108]: x=cls(t) x(1,2) # In[109]: v = vec_t(1,2,3) cls(v) # In[110]: t.linear = 4 # In[111]: dir(t) # In[114]: t.__yivo__() # In[ ]: