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__
?
精彩评论