Asdfg
Asdfg

Reputation: 12233

How to call vars on an instance to also have vars called on attributes that are also instances

How do I get vars function to return the properties of a class if a property is of type another class?

Example:

class User:
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name
        self.geo = GeoInformation()


class GeoInformation:
    def __init__(self, city="", state="", zipcode="", country=""):
        self.city = city
        self.state = state
        self.zipcode = zipcode
        self.country = country


user = User("John", "Smith")
user.geo.city = "SomeCity"
user.geo.state = "SomeState"
user.geo.zipcode = "SomeZipcode"
user.geo.country = "SomeCountry"

print(vars(user))

Output I am getting:

{'first_name': 'John', 'last_name': 'Smith', 'geo': <class '__main__.GeoInformation'>}

Output I am expecting:

{'first_name': 'John', 'last_name': 'Smith', 'geo': {'city':'someCity', 'state':'someState', 'zipcode':'someZipcode', 'country':'someCountry'}}

If this is not the right way to do what I am trying to achieve, please suggest the better way.

Upvotes: 1

Views: 207

Answers (2)

Green Cloak Guy
Green Cloak Guy

Reputation: 24691

Here's a function to run vars recursively and return the result:

def recursive_vars(obj):
    dct = vars(obj)
    for k, v in dct.items():
        if hasattr(v, "__dict__"):  # check if we can go further recursively
            dct[k] = recursive_vars(v)
    return dct

Now, any value that was a class should be replaced by whatever vars() would have produced for that class, and so on down the chain.

Upvotes: 2

xeno097
xeno097

Reputation: 13

You could define a __repr__ method in your GeoInformation class that calls var on itself so when you call print(vars(user)) it will also print out the data in your geo property

class User:
    def __init__(self, first_name, last_name,city, state, zipcode, country):
        self.first_name = first_name
        self.last_name = last_name
        self.geo = GeoInformation(city, state, zipcode, country)

class GeoInformation:
    def __init__(self, city="", state="", zipcode="", country=""):
        self.city = city
        self.state = state
        self.zipcode = zipcode
        self.country = country
    def __repr__(self):
        return str(vars(self))


user = User("John", "Smith","SomeCity","SomeState","SomeZipcode","SomeCountry")


print(vars(user))

Output:

{'first_name': 'John', 'last_name': 'Smith', 'geo': {'city': 'SomeCity', 'state': 'SomeState', 'zipcode': 'SomeZipcode', 'country': 'SomeCountry'}}

Upvotes: 0

Related Questions