Luke Brooks via plug on 10 Jul 2021 15:40:09 -0700


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PLUG] Python nested dict data structure


I was looking into how to make it json serializable when I wrote that but it seemed like there wasn't a way to do it without writing a custom json encoder class and forcing the caller to pass in my custom class.  It would probably be easier to simply add a method to convert the whole thing back to a standard python dictionary and then serialize that.

I can write that for you if you want but it looks like you'd rather go another route.  I guess for me it's just kind of interesting that in theory we could write a python class that more or less behaves like a perl object.  Weak typing is a hell of a drug.  I was really considering for a minute making a whole project of this and creating a package for it but it's probably not that useful anyway and I'm sure someone's already done it.

On Sat, Jul 10, 2021, 3:12 PM JP Vossen via plug <plug@lists.phillylinux.org> wrote:
On 7/10/21 1:22 PM, gary@duzan.org wrote:
> Adding "import numbers" on a line before "class PerlObject:" should do it.

Duh.  Thank you, yes, that works.

Code:
```
      1 #!/usr/bin/env python3
      2 # dict3.py--do I REALLY have to build a CLASS just for NESTED dicts!?
      3 # 2021-07-10
      4 # From Luke Brooks in EM "Re: [PLUG] Python nested dict data structure"
      5
      6 import json  # But doesn't work because PerlObject() isn't JSON serializable
      7 import numbers
      8
      9 class PerlObject:
     10
     11     def __init__(self, value=None):
     12         self.Value = value
     13
     14     def __getitem__(self, key):
     15         self.checkType(dict)
     16         if key not in self.Value:
     17             self.Value[key] = PerlObject()
     18         return self.Value[key]
     19
     20     def __setitem__(self, key, value):
     21         self.checkType(dict)
     22         if isinstance(value, PerlObject):
     23             self.Value[key] = value
     24         else:
     25             self.Value[key] = PerlObject(value)
     26
     27     def __delitem__(self, key):
     28         self.checkType(dict)
     29         if key in self.Value:
     30             del self.Value[key]
     31
     32     def __add__(self, other):
     33         self.checkType(numbers.Number, 0)
     34         if isinstance(other, PerlObject):
     35             other.checkType(numbers.Number, 0)
     36             return PerlObject(self.Value + other.Value)
     37         return PerlObject(self.Value + other)
     38
     39     def checkType(self, t, dfv=None):
     40         if self.Value == None:
     41             if dfv != None:
     42                 self.Value = dfv
     43             else:
     44                 self.Value = t()
     45         elif not isinstance(self.Value, t):
     46             raise Exception("Object does not support operation")
     47
     48     def __repr__(self):
     49         return str(self)
     50
     51     def __str__(self):
     52         return str(self.Value)
     53
     54 d = PerlObject()
     55
     56 # Main
     57 company = 'Acme Inc'  # Key in both (all) files
     58
     59 # First read file 1, containing: Company\tRegion\tOther-stuff-I-don't-care-about-here
     60 d[company]['region'] = 'US'
     61
     62 # ...LATER...read file 2, containing *multiple records* of: Company\tthis\tthat\Counter
     63 d[company]['counter'] += 2
     64 d[company]['counter'] += 3
     65
     66 # ...STILL LATER...read file 3, containing even more crazy stuff
     67 d[company]['subkey']['subsubkey'] = 'foo'
     68 d[company]['subkey']['subsubint'] += 6
     69
     70 print(d)
     71 #TypeError: Object of type 'PerlObject' is not JSON serializable
     72 #print(json.dumps(d, indent=2, sort_keys=True))  # Pretty but needs: import json
```

Output:
```
$ ./dict3.py
{'Acme Inc': {'region': US, 'counter': 5, 'subkey': {'subsubkey': foo, 'subsubint': 6}}}
```

If I try to `print(json.dumps(...` I get this:
```
$ ./dict3.py
Traceback (most recent call last):
   File "./dict3.py", line 71, in <module>
     print(json.dumps(d, indent=2, sort_keys=True))  # Pretty but needs: import json
   File "/usr/lib/python3.6/json/__init__.py", line 238, in dumps
     **kw).encode(obj)
   File "/usr/lib/python3.6/json/encoder.py", line 201, in encode
     chunks = list(chunks)
   File "/usr/lib/python3.6/json/encoder.py", line 437, in _iterencode
     o = _default(o)
   File "/usr/lib/python3.6/json/encoder.py", line 180, in default
     o.__class__.__name__)
TypeError: Object of type 'PerlObject' is not JSON serializable
```

Which makes sense because as Luke already said, "[the class is] pretty limited in functionality so far since I made it specifically for this example."

Thanks,
JP
--  -------------------------------------------------------------------
JP Vossen, CISSP | http://www.jpsdomain.org/ | http://bashcookbook.com/
___________________________________________________________________________
Philadelphia Linux Users Group         --        http://www.phillylinux.org
Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce
General Discussion  --   http://lists.phillylinux.org/mailman/listinfo/plug
___________________________________________________________________________
Philadelphia Linux Users Group         --        http://www.phillylinux.org
Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce
General Discussion  --   http://lists.phillylinux.org/mailman/listinfo/plug