Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursively print all attributes, lists, dicts, etc of an object in Python

Using Python 2.7.10, I have this script:

#!/usr/bin/python

#Do `sudo pip install boto3` first
import boto3
import json

def generate(key, value):
    """
    Creates a nicely formatted Key(Value) item for output
    """
    return '{}={}'.format(key, value)

def main():
    ec2 = boto3.resource('ec2', region_name="us-west-2")
    volumes = ec2.volumes.all()
    for vol in volumes:
        #print(vol.__str__())
        #print(vol.__dict__)
        print vol

     # vol object has many attributes, which can be another class object. 
     # For ex:
            #vol.volume_id),
            #vol.availability_zone),
            #vol.volume_type),

        # only process when there are tags to process
        # HERE: tags is another object which can contain a dict/list
        #if vol.tags:
        #    for _ in vol.tags:
        #        # Get all of the tags
        #        output_parts.extend([
        #            generate(_.get('Key'), _.get('Value')),
        #        ])


        # output everything at once.
        print ','.join(output_parts)

if __name__ == '__main__':
    main()

Is there a single function which can recursively print all the object's attributes using a single call? How can I print the values of val.xxxxx and val.tags.xxxx in one call.

I tried printing the object using .__dict__ or .__str__() but it didn't help.

like image 532
AKS Avatar asked Oct 20 '25 01:10

AKS


1 Answers

Here's a function that you can drop into the str for your object. You can also call it directly, passing in the object you wish to print. The function returns a string that represents a nicely formatted walk of your object's contents.

Credit goes to @ruud from forum.pythonistacafe.com for coming up with this solution.

def obj_to_string(obj, extra='    '):
    return str(obj.__class__) + '\n' + '\n'.join(
        (extra + (str(item) + ' = ' +
                  (obj_to_string(obj.__dict__[item], extra + '    ') if hasattr(obj.__dict__[item], '__dict__') else str(
                      obj.__dict__[item])))
         for item in sorted(obj.__dict__)))


class A():
    def __init__(self):
        self.attr1 = 1
        self.attr2 = 2
        self.attr3 = 'three'


class B():
    def __init__(self):
        self.a = A()
        self.attr10 = 10
        self.attrx = 'x'


class C():
    def __init__(self):
        self.b = B()


class X():

    def __init__(self):
        self.abc = 'abc'
        self.attr12 = 12
        self.c = C()

    def __str__(self):
        return obj_to_string(self)


x = X()

print(x)

Output:

<class '__main__.X'>
    abc = abc
    attr12 = 12
    c = <class '__main__.C'>
        b = <class '__main__.B'>
            a = <class '__main__.A'>
                attr1 = 1
                attr2 = 2
                attr3 = three
            attr10 = 10
            attrx = x
like image 66
Mike from PSG Avatar answered Oct 21 '25 17:10

Mike from PSG



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!