python – 比较dict子类的实例
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 比较dict子类的实例,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3349字,纯文字阅读大概需要5分钟。
内容图文
![python – 比较dict子类的实例](/upload/InfoBanner/zyjiaocheng/761/59b95b3ce8454438a59b4639d2bba0b2.jpg)
我有子类dict添加一个额外的方法(所以没有覆盖).
现在,我尝试比较其中两个子类,我得到一些奇怪的东西:
>>> d1.items() == d2.items()
True
>>> d1.values() == d2.values()
True
>>> d1.keys() == d2.keys()
True
>>> d1 == d2
False
编辑
那真是太奇怪了……我根本不明白!谁有洞察dict.eq是如何实现的?
以下是所有代码:
# ------ Bellow is my dict subclass (with no overriding) :
class ClassSetDict(dict):
def subsetget(self, klass, default=None):
class_sets = set(filter(lambda cs: klass <= cs, self))
# Eliminate supersets
for cs1 in class_sets.copy():
for cs2 in class_sets.copy():
if cs1 <= cs2 and not cs1 is cs2:
class_sets.discard(cs2)
try:
best_match = list(class_sets)[0]
except IndexError:
return default
return self[best_match]
# ------ Then an implementation of class sets
class ClassSet(object):
# Set of classes, allowing to easily calculate inclusions
# with comparison operators : `a < B` <=> "A strictly included in B"
def __init__(self, klass):
self.klass = klass
def __ne__(self, other):
return not self == other
def __gt__(self, other):
other = self._default_to_singleton(other)
return not self == other and other < self
def __le__(self, other):
return self < other or self == other
def __ge__(self, other):
return self > other or self == other
def _default_to_singleton(self, klass):
if not isinstance(klass, ClassSet):
return Singleton(klass)
else:
return klass
class Singleton(ClassSet):
def __eq__(self, other):
other = self._default_to_singleton(other)
return self.klass == other.klass
def __lt__(self, other):
if isinstance(other, AllSubSetsOf):
return issubclass(self.klass, other.klass)
else:
return False
class AllSubSetsOf(ClassSet):
def __eq__(self, other):
if isinstance(other, AllSubSetsOf):
return self.klass == other.klass
else:
return False
def __lt__(self, other):
if isinstance(other, AllSubSetsOf):
return issubclass(self.klass, other.klass) and not other == self
else:
return False
# ------ and finally the 2 dicts that don't want to be equal !!!
d1 = ClassSetDict({AllSubSetsOf(object): (int,)})
d2 = ClassSetDict({AllSubSetsOf(object): (int,)})
解决方法:
你所看到的问题与子类化dict没有任何关系.事实上,使用常规字典可以看到这种行为.问题是如何定义您正在使用的密钥.一个简单的类,如:
>>> class Foo(object):
... def __init__(self, value):
... self.value = value
...
... def __eq__(self, other):
... return self.value == other.value
...
足以证明问题:
>>> f1 = Foo(5)
>>> f2 = Foo(5)
>>> f1 == f2
True
>>> d1 = {f1: 6}
>>> d2 = {f2: 6}
>>> d1.items() == d2.items()
True
>>> d1 == d2
False
缺少的是你忘了定义__hash__.每次更改类的相等语义时,都应确保__hash__方法与它一致:当两个对象相等时,它们必须具有相等的哈希值. dict行为很大程度上取决于键的哈希值.
当你从object继承时,你自动获得__eq__和__hash__,前者比较对象标识,后者返回对象的地址(所以他们同意),但是当你改变__eq__时,你仍然看到旧的__hash__,不再同意和dict迷失了.
只需提供一个__hash__方法,以稳定的方式组合其属性的哈希值.
>>> class Bar(object):
... def __init__(self, value):
... self.value = value
...
... def __eq__(self, other):
... return self.value == other.value
...
... def __hash__(self):
... return hash((Bar, self.value))
...
>>> b1 = Bar(5)
>>> b2 = Bar(5)
>>> {b1: 6} == {b2: 6}
True
>>>
以这种方式使用__hash__时,确保在创建对象后属性不会(或更好,不能)更改也是一个好主意.如果哈希值在dict中收集时发生变化,则密钥将“丢失”,并且可能发生各种奇怪的事情(甚至比您最初询问的问题更奇怪)
内容总结
以上是互联网集市为您收集整理的python – 比较dict子类的实例全部内容,希望文章能够帮你解决python – 比较dict子类的实例所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。