Coding style 类对象并比较特定属性

Coding style 类对象并比较特定属性,coding-style,python,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__

我有以下代码

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__
现在我想用这个代码,只对一组特定的属性(“键”)执行
\uuuuueq\uuuuuu
。所以我把它改成这样:

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
我读过以下两篇精彩的文章(和),我的基本问题是:

这是正确的方法还是有更好的方法在python中实现这一点?

很明显,TMTOWTDI-但我想保持并遵循一个标准的pythonic方法。谢谢

更新

有人问我为什么不在班上修改属性。这是一个很好的问题,原因如下。这样做的目的是获取多个不相关的员工记录,并构建员工的完整图片。例如,我从ldap、lotusnotes、unix passwd文件、bugzilla数据等获取数据。每种数据都有uniqattr,因此我将它们概括为一个人。这给了我一个快速一致的方法来比较旧记录和新记录。嗯。谢谢

**更新第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)

感谢两位男士的评论

您可以通过以下方式简化比较:

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
致:


您可以通过以下方式简化比较:

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
致:


我肯定会做一些小的增强(bug修复)

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

\uuuu str\uuuu
不允许返回dict:它必须返回字符串

不可比较对象之间的
\uuu eq\uuu
不应引发-它应返回False

除了bug,您可以使用
self.\uu dict\uuu
非常简洁地获取对象的状态,或者使用
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)

我肯定会做一些小的增强(bug修复)

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

\uuuu str\uuuu
不允许返回dict:它必须返回字符串

不可比较对象之间的
\uuu eq\uuu
不应引发-它应返回False

除了bug,您可以使用
self.\uu dict\uuu
非常简洁地获取对象的状态,或者使用
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)

我不理解你的构造函数:你每次都要生成一个person()并传入属性列表?我原以为属性是person类的固定特征。也许是一个如何命名的例子?好问题。我从一组固定的属性开始,但我发现表现一个人的方式不同。所以我想我应该传递一个属性列表。我会解释我为什么要这么做。好鹰眼。正如我在回答中提到的,如果
其他
中缺少
self
中的一些有效键,你仍然会在
中崩溃。我不理解你的构造函数:你要生成一个人()并每次传入属性列表?我原以为属性是person类的固定特征。也许是一个如何命名的例子?好问题。我从一组固定的属性开始,但我发现表现一个人的方式不同。所以我想我应该传递一个属性列表。我会解释我为什么要这么做。好鹰眼。正如我在回答中提到的,如果
其他
中缺少一些在
self
中有效的键,你仍然会在
中崩溃。Alex,我一直喜欢研究你的帖子。毫无疑问,您的知识和分享意愿是一流的。感谢您在查看您的代码后-您没有完全按照我的要求进行操作-因此我更新了我的学习内容。正如我在上面的回答中提到的,我还对您编辑的Q进行了评论,如果
\uuuuuu eq\uuu
中的一些有效键在
其他
中丢失,您仍然会在
中崩溃。另外,你的
\uuuueq\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。所以我还是不清楚你想做什么。也许可以进一步编辑答案,给出两个人物实例的玩具例子,它们应该是平等的还是不同的?Alex,我一直喜欢研究你的帖子。毫无疑问,您的知识和分享意愿是一流的。感谢您在查看您的代码后-您没有完全按照我的要求进行操作-因此我更新了我的学习内容。正如我在上面的回答中提到的,我还对您编辑的Q进行了评论,如果
\uuuuuu eq\uuu
中的一些有效键在
其他
中丢失,您仍然会在
中崩溃。另外,你的
\uuuueq\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。所以我还是不清楚你想说什么