类对象和比较特定属性

时间:2009-11-10 15:40:08

标签: coding-style python

我有以下代码。

class person(object):

    def __init__(self, keys):
        for item in keys:
            setattr(self, item, None)

    def __str__(self):
        return str(self.__dict__)

    def __eq__(self, other) :        
        return self.__dict__ == other.__dict__

现在我想接受这个代码,只对特定的一组attrs(“keys”)执行__eq__。所以我改变它来做到这一点:

class person(object):

    def __init__(self, keys):
        self.valid_keys = keys
        for item in keys:
            setattr(self, item, None)

    def __str__(self):
        return dict([(i, getattr(self, i)) for i in self.valid_keys ])

    def __eq__(self, other) :
        assert isinstance(other, person)
        self_vals = [ getattr(self, i) for i in self.valid_keys ]
        other_vals = [ getattr(other, i) for i in self.valid_keys ]
        return self_vals == other_vals

我已阅读以下两篇精彩帖子(herehere),我的基本问题是:

这是正确的方法,还是有更好的方法在python中执行此操作?

显然TMTOWTDI - 但我想保持并遵循标准的pythonic方法。谢谢!

更新

有人问我为什么不修理课堂上的激光器。这是一个很好的问题,这就是原因。这样做的目的是获取几个解散的员工记录,并建立一个完整的员工图片。例如,我从ldap,lotus notes,unix passwd文件,bugzilla数据等获取我的数据。每个都有uniq attrs,所以我将它们推广到一个人。这为我提供了一种快速一致的方法来将旧记录与新记录进行比较。 HTH。感谢

**更新Pt.2 **

以下是我最终的结果:

class personObj(object):

    def __init__(self, keys):
        self.__dict__ = dict.fromkeys(keys)
        self.valid_keys = keys

    def __str__(self):
        return str([(i, getattr(self, i)) for i in self.valid_keys ])

    def __eq__(self, other):
        return isinstance(other, personObj) and all(getattr(self, i) == getattr(other, i) for i in self.valid_keys)

感谢两位男士的评论!

2 个答案:

答案 0 :(得分:2)

我肯定会做一些小的改进(错误修复)。

特别是,如果属性不存在,则使用两个参数调用的getattr会引发ArgumentError,因此如果您使用不同的键比较两个实例,则可能会出现该异常。你可以用三个args来调用它(当属性不存在时,第三个作为默认值返回) - 在这种情况下只是不要使用None作为第三个arg,因为它通常是你通常的具有值(使用sentinel值作为第三个arg)。

__str__不允许返回一个字典:它必须返回一个字符串。

__eq__之间不可比较的对象不应该引发 - 它应该返回False。

分开,您可以使用self.__dict__非常紧凑地获取对象的状态,或者使用vars(self)更优雅地获取对象的状态(尽管如此,您无法使用后一种语法重新分配整个dict)。这一点知识可以让你以更高层次的抽象方式完全重做你的课程 - 更加紧凑和迅速:

class person(object):

    def __init__(self, keys):
        self.__dict__ = dict.fromkeys(keys)

    def __str__(self):
        return str(vars(self))

    def __eq__(self, other):
        return isinstance(other, person) and vars(self) == vars(other)

答案 1 :(得分:1)

您可以简化比较:

self_vals = [ getattr(self, i) for i in self.valid_keys ]
other_vals = [ getattr(other, i) for i in self.valid_keys ]
return self_vals == other_vals

为:

return all(getattr(self, i) == getattr(other, i) for i in self.valid_keys)