在For循环中获取属性名称

时间:2011-06-08 19:00:39

标签: python django

如何获取对象的属性名称和值?我正在尝试将它转换为字典,以便我可以轻松地JSON序列化对象。

代码:

class User:
    ...
    def to_dict( self ):
        dict = {}
        for key, value in filter( lambda aname: not aname.startswith('_'), dir(self) ):
            dict[key] = value
    return dict

错误:

too many values to unpack

使用:

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

3 个答案:

答案 0 :(得分:3)

您收到该错误是因为filter( lambda aname: not aname.startswith('_'), dir(u) )返回单个项目列表,并且您尝试解压缩两个值(for key, value)。使用dir代替__dict__的一个潜在原因可能是您关心的是类别或者继承的attrs。由于__dict__仅包含实例attrs,因此无法找到它们。

class Base(object):
    x = 1

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

>>> u = User(3)

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

如果您仍想使用dir,可以这样做:

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}

明确定义属性as in this answer可能是最好的路径。

答案 1 :(得分:1)

使用self.__dict__。它是一个表示对象命名空间的字典。

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

请注意,根据您的代码段,.to_dict()返回的dict将包含键'to_dict',因为该函数不以下划线开头。你帖子中可能是一个简单的错误。

如果要包含在返回的字典中的属性列表很小(并且变化不大),我建议明确说明并列出它们

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])

答案 2 :(得分:0)

我可能会遗漏一些东西,但为什么不简单user.__dict__