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。所以我还是不清楚你想说什么