我还有一个问题要问你。

我有一个带有列表“元信息”的python 类。此列表包含我的类可能包含的变量名称。我编写了一个 __eq__ 方法,如果 selfother 具有来自 metainfo 的相同变量并且这些变量具有相同的值,则该方法返回 True。

这是我的实现:

 def __eq__(self, other):
    for attr in self.metainfo:
      try:
        ours = getattr(self, attr)
        try:
          theirs = getattr(other, attr)
          if ours != theirs:
            return False
        except AttributeError:
          return False
      except AttributeError:
        try:
          theirs = getattr(other, attr)
          return False
        except AttributeError:
          pass
    return True

有没有人对我如何让这段代码更容易理解有什么建议?随心所欲地无情。

最佳答案

使用 getattr 的第三个参数设置不同的默认值:

def __eq__(self, other):
    return all(getattr(self, a, Ellipsis) == getattr(other, a, Ellipsis)
               for a in self.metainfo)

作为默认值,设置一些永远不会成为实际值的东西,例如 Ellipsis †。因此,仅当两个对象都包含某个属性的相同值或两者都没有所述属性时,这些值才会匹配。

编辑 :正如 Nadia 指出的那样, NotImplemented 可能是一个更合适的常量(除非您要存储丰富比较的结果......)。

编辑 2: 事实上,正如 Lac 指出的那样,只使用 hasattr 会产生更易读的解决方案:
def __eq__(self, other):
    return all(hasattr(self, a) == hasattr(other, a) and
               getattr(self, a) == getattr(other, a) for a in self.metainfo)

†:如果需要额外的帮助,您可以编写...而不是Ellipsis,从而编写getattr(self, a, ...)等。不,不要这样做:)

10-06 08:43