0

Here is a dictionary I have as input

user_vars = {
  "verbose": true,
  "testing": false,
  "login": {
    "username": "theadmin",
    "password": "password123"
  },
  "interfaces": {
    "trust": {
      "ip": "10.8.10.1/30"
    },
    "untrust": {
      "ip": "10.9.10.1/30"
    }
  }
}

I found this article on how to create an object from a class: https://bobbyhadz.com/blog/python-convert-nested-dictionary-to-object#:~:text=To%20convert%20a%20nested%20dictionary,the%20key%20to%20the%20value.

So I did this:

class payloadGen:
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            if isinstance(value, dict):
                self.__dict__[key] = payloadGen(**value)
            else:
                self.__dict__[key] = value

So when I call it I am able to do the following just fine:

customer = payloadGen(**user_vars)
print(customer.interfaces.trust.ip)
print(customer.verbose)

#output
10.8.10.1/30
True

But when I try to print a parent of nested values, I get the object memory address:

print(customer.interfaces)
#output
<payloadgen.payloadGen object at 0x7fbe8cedd7f0>

This is expected. What I want to be able to do is print all child keys and values recursively:

print(customer.interfaces)
#wanted output
"trust": {"ip": "10.8.10.1/30"},"untrust": {"ip": "10.9.10.1/30"}

I realize this maybe a complicated affair. I am new to class's, constructors, inherence, and objects. So if need to do some more reading on how to accomplish this please point me in the right direction.

EDIT: Thanks to @Axe319. I needed to just adjust the class to add a representor call, and use a lambda function.

class payloadGen:
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            if isinstance(value, dict):
                self.__dict__[key] = payloadGen(**value)
            else:
                self.__dict__[key] = value

    __repr__ = lambda self: repr(self.__dict__)

Now I can call individual parent entries and all child parent/children display

customer = payloadGen(**user_vars)
print(customer.interfaces.trust.ip)
print(customer.interfaces)
#output
10.8.10.1/30
{interfaces": {"trust": {"ip": "10.8.10.1/30"},"untrust": {"ip": "10.9.10.1/30"}}}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Dave
  • 727
  • 1
  • 9
  • 20
  • Then you just need to add a `__str__` or `__repr__` method that returns the string you want to be displayed. – Tim Roberts Dec 07 '22 at 19:06
  • This: https://stackoverflow.com/questions/1535327/how-to-print-instances-of-a-class-using-print – Adam Smooch Dec 07 '22 at 19:07
  • I figured it out, this post details how to do what I want to do: https://goodcode.io/articles/python-dict-object/ – Dave Dec 07 '22 at 19:18
  • 1
    @Dave the easy way would be to just put a `__repr__ = lambda self: repr(self.__dict__)` in the body of your class. – Axe319 Dec 07 '22 at 19:20
  • 1
    @Axe319, that actually works better than the article I just shared. Its prefect! Thank you! I will edit my post. – Dave Dec 07 '22 at 19:29

0 Answers0