开发者

Get Attribute Name in For Loop

开发者 https://www.devze.com 2023-03-11 18:50 出处:网络
How do I get the attribute names and values of an object? I\'m attempting to cast it to a dictionary so that I can easily JSON serialize the object.

How do I get the attribute names and values of an object? I'm attempting to cast it to a dictionary so that I can easily JSON serialize the object.

Code:

class User:
    ...
    def to_dict( self ):
        dict = {}
        for key, value in filter( lambda aname: not aname.startswith('_'), dir(self) ):
            dict[key] = value开发者_运维知识库
    return dict

Error:

too many values to unpack

Use:

user = User({
    's_email': 'bob@email.com',
    's_password': 'password',
})
user.to_dict()
# JSON Serialize


You get that error because filter( lambda aname: not aname.startswith('_'), dir(u) ) returns a list of single items, and you are trying to unpack two values (for key, value). One potential reason to use dir instead of __dict__ might be that you care about class attrs, or inherited attrs. Since __dict__ only contains instance attrs it won't find those.

class Base(object):
    x = 1

class User(Base):
    y = 2
    def __init__(self, z):
        self.z = z

>>> u = User(3)

>>> u.__dict__
<<< {'z': 3}

If you wanted to use dir still, you can do so like this:

def to_dict(self):
    d = {}
    for k, v in [(x, getattr(self, x)) for x in dir(self) if not x.startswith('_')]:
        if not hasattr(v, '__call__'): d[k] = v # skip methods
    return d

>>> u = User(3)

>>> u.to_dict()
<<< {'x': 1, 'y': 2, 'z': 3}

Defining the attributes explicitly as in this answer would probably be the best route, though.


Use self.__dict__. It is a dictionary representing the namespace of the object.

class User:
    ...
    def to_dict(self):
        return dict(
            [(k, v) for k, v in self.__dict__.iteritems() if not k.startswith('_')]
        )

Note that given your code snippet, the dict returned by .to_dict() would contain the key 'to_dict' as the function does not start with an underscore. Probably a simple mistake in your post.

If the list of attributes that you want to include in the returned dict is small (and doesn't change much), I suggest being explicit about it and listing them

class User(object):
    data_attributes = ('s_email', 's_password')
    def to_dict(self):
        return dict([(attr, getattr(self, attr) for attr in self.data_attributes])


I might be missing something, but why not simply user.__dict__?

0

精彩评论

暂无评论...
验证码 换一张
取 消