-
Notifications
You must be signed in to change notification settings - Fork 0
/
misc.py
90 lines (71 loc) · 2.16 KB
/
misc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import json
import datetime
class A:
def __init__(self):
self.a = ''
self.b = ''
self.c=AA()
self.d=datetime.datetime.now()
class AA:
def __init__(self):
self.c='fddsfsdf'
A.JsonFields = ['a', 'b', 'c', 'd:dt']
AA.JsonFields = ['c']
CLASS_MAP = {A.__name__: A, AA.__name__: AA}
class B:
def __init__(self):
self.a = ''
self.b = ''
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if hasattr(obj.__class__, 'JsonFields'):
fields = obj.__class__.JsonFields
d = {'__class__': obj.__class__.__name__}
for fld in fields:
assert isinstance(fld, str)
pos = fld.find(':')
if pos > 0:
fld = fld[0:pos]
if hasattr(obj, fld):
d[fld] = getattr(obj, fld)
return d
elif isinstance(obj, datetime.datetime):
return obj.timestamp()
else:
return obj.__dict__
class CustomDecoder(json.JSONDecoder):
def __init__(self):
super().__init__(object_hook=self.fdms_object_hook)
@staticmethod
def fdms_object_hook(d):
obj = None
if '__class__' in d:
class_name = d['__class__']
if class_name in CLASS_MAP:
obj = CLASS_MAP[class_name]()
if obj is None:
return d
if not hasattr(obj.__class__, 'JsonFields'):
return d
for fld in obj.__class__.JsonFields:
assert isinstance(fld, str)
pos = fld.find(':')
type = None
if pos > 0:
type = fld[pos+1:]
fld = fld[0:pos]
if fld in d:
value = d[fld]
if type is not None:
if type == 'dt' and isinstance(value, float):
value = datetime.datetime.fromtimestamp(value)
if hasattr(obj, fld):
setattr(obj, fld, value)
return obj
a = A()
a.a = 'dfsdsfdsf'
a.b = 'fdsfdsfsdff'
j = json.dumps(a, cls=CustomEncoder)
print(j)
obj = json.loads(j, cls=CustomDecoder)
print(obj)