gpt4 book ai didi

Python:这是覆盖 __eq__ 和 __hash__ 的好方法吗?

转载 作者:IT老高 更新时间:2023-10-28 20:55:22 26 4
gpt4 key购买 nike

我是 Python 新手,我想确保我正确地覆盖了 __eq____hash__,以免以后造成痛苦的错误:

(我使用的是 Google App Engine。)

class Course(db.Model):
dept_code = db.StringProperty()
number = db.IntegerProperty()
title = db.StringProperty()
raw_pre_reqs = db.StringProperty(multiline=True)
original_description = db.StringProperty()

def getPreReqs(self):
return pickle.loads(str(self.raw_pre_reqs))

def __repr__(self):
title_msg = self.title if self.title else "Untitled"
return "%s %s: %s" % (self.dept_code, self.number, title_msg)

def __attrs(self):
return (self.dept_code, self.number, self.title, self.raw_pre_reqs, self.original_description)

def __eq__(self, other):
return isinstance(other, Course) and self.__attrs() == other.__attrs()

def __hash__(self):
return hash(self.__attrs())

稍微复杂一点的类型:

class DependencyArcTail(db.Model):
''' A list of courses that is a pre-req for something else '''
courses = db.ListProperty(db.Key)

''' a list of heads that reference this one '''
forwardLinks = db.ListProperty(db.Key)

def __repr__(self):
return "DepArcTail %d: courses='%s' forwardLinks='%s'" % (id(self), getReprOfKeys(self.courses), getIdOfKeys(self.forwardLinks))

def __eq__(self, other):
if not isinstance(other, DependencyArcTail):
return False

for this_course in self.courses:
if not (this_course in other.courses):
return False

for other_course in other.courses:
if not (other_course in self.courses):
return False

return True

def __hash__(self):
return hash((tuple(self.courses), tuple(self.forwardLinks)))

一切看起来都不错?

更新以反射(reflect) @Alex 的评论

class DependencyArcTail(db.Model):
''' A list of courses that is a pre-req for something else '''
courses = db.ListProperty(db.Key)

''' a list of heads that reference this one '''
forwardLinks = db.ListProperty(db.Key)

def __repr__(self):
return "DepArcTail %d: courses='%s' forwardLinks='%s'" % (id(self), getReprOfKeys(self.courses), getIdOfKeys(self.forwardLinks))

def __eq__(self, other):
return isinstance(other, DependencyArcTail) and set(self.courses) == set(other.courses) and set(self.forwardLinks) == set(other.forwardLinks)

def __hash__(self):
return hash((tuple(self.courses), tuple(self.forwardLinks)))

最佳答案

第一个很好。第二个问题有两个原因:

  1. .courses
  2. 中可能有重复项
  3. 具有相同 .courses 但不同 .forwardLinks 的两个实体会比较相等但具有不同的哈希值

我将通过使相等性依赖于类(class)和前向链接来解决第二个问题,但是对集合的两个更改(因此没有重复),对于散列也是如此。即:

def __eq__(self, other):
if not isinstance(other, DependencyArcTail):
return False

return (set(self.courses) == set(other.courses) and
set(self.forwardLinks) == set(other.forwardLinks))

def __hash__(self):
return hash((frozenset(self.courses), frozenset(self.forwardLinks)))

这当然是假设前向链接对一个对象的“真实值(value)”至关重要,否则它们应该从 __eq____hash__

Edit:从 __hash__ 调用中删除了对 tuple 的调用,这些调用充其量是多余的(并且可能具有破坏性,正如@Mark 的评论所建议的那样[[tx!!!]]);正如@Phillips [[tx!!!]] 的评论所建议的,将散列中的 set 更改为 frozenset

关于Python:这是覆盖 __eq__ 和 __hash__ 的好方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3076967/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com