- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
目前,我正在研究 Python 的内置类型。我很困惑调用什么方法来检查键是否在字典中。例如,如果我检查 int
类型的键是否在字典中,则仅当 dictionary.keys() 包含它时,才会在后台调用 __eq__()
方法.如果不是,则不调用 __eq__()
。
这是一个代码示例:
dict = {
1: "Hello",
2: "World",
4: "Foo"
}
assert 1 in dict.keys() # the __eq__() method of int is invoked
assert not(3 in dict.keys()) # no __eq__() method of int is invoked
我知道,字典包含哈希(键)、键和值的元组。但是我有点困惑,为什么 __eq__()
没有在第二个断言中被调用。
为了测试这个行为,我从 int
继承并设置了一些断点。这是我的自定义 int
类的摘录:
tint(int):
def __new__(cls, value, *args, **kw):
return super(tint, cls).__new__(cls, value)
def __init__(self, value):
super().__init__()
def __eq__(self, other):
return super().__eq__(other) # with breakpoints
def __ne__(self, other):
return super().__ne__(other) # with breakpoints
def __hash__(self):
return tint(super().__hash__()) # with breakpoints
我在 Ubuntu 18.04.1 LTS 上使用 Python 3.6.5 版。
最佳答案
要在字典中找到一个键,您首先要通过哈希找到候选者,然后看看它是侥幸(尽管哈希相同,但对象不同)还是您真正想要的键。因此,如果您在该散列下找不到任何内容,则没有什么可 eq 的。
想象一下,您正在聚会上寻找熟人,但不知道她是否在场。她有红色的头发。通常,你会寻找红发女孩,然后去面对她们,看看是不是真的是她。如果还没有红发女孩来,检查聚会上的每一个人是没有意义的。 (假设您的 friend 不喜欢日常染色工作。)
编辑:CPython 将字典存储在一个数组中,其中主数组位置由散列确定;如果那个位置被占用,它会以数学上确定的方式跳到下一个候选位置。由于填充的位置因此可以保存“正确的”散列或不相关的散列,当查找散列时,CPython 将从主要位置开始,然后继续比较散列,直到它确定所搜索的 key 不可能存在。此时哈希是普通的低级整数,而不是 Python 对象,这解释了为什么哈希比较不会触发 __eq__
。
请注意源代码中的一个可爱的优化:对于每个候选对象,CPython 首先检查对象身份;只有这样它才会检查哈希值是否仍然相同,如果是,则进行慢速检查以查看对象是否相等(使用 PyObject_RichCompareBool
,最终调用 __eq__
)。为什么这很重要?看这里:
class Foo:
def __eq__(self, other):
return False # This shouldn't match...
def __hash__(self):
return 7
f = Foo()
d = { f: "Yes!" }
print(d[f]) # ...and yet it does! :)
# => "Yes!"
关于Python:如果键不在字典中,为什么不调用 __eq__()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52037437/
根据 this page , set.intersection 使用 __eq__ 方法测试元素是否相等。谁能向我解释为什么这会失败? >>> Class Foo(object): >>> d
所以下面的内置类有一个 __eq__ 属性,(我假设)这就是为什么你可以测试它们的实例是否相等: >>> 1.2.__eq__( 1.2 ) True >>> 1.2 == 1.2 True >>>
在我正在处理的问题中,数据标识符的形式为 scope:name,既是 scope 又是 name 字符串. name 由点分隔的不同部分,如 part1.part2.part3.part4.part5
我有一组对象,并且有兴趣从该组中获取特定对象。经过一番研究,我决定使用此处提供的解决方案:http://code.activestate.com/recipes/499299/ 问题是它似乎不起作用。
我有一个父数据类和一个子数据类继承第一个类。我重新定义了__eq__()父数据类中的方法。但是当我比较对象子数据类时,它不使用 __eq__()父数据类中定义的方法。为什么会发生这种情况?我该如何解决
我正在用 Python 编写 DSL,我想重载运算符以便能够轻松编写 DSL 的表达式。例如,我想编写 Var("a") + Var("b") 并获得 Add(Var("a"), Var("b") 的
如果我像这样在 Python 2.7 中定义一个对象: class C(object): def __eq__(self, other): return object.__eq
目前,我正在研究 Python 的内置类型。我很困惑调用什么方法来检查键是否在字典中。例如,如果我检查 int 类型的键是否在字典中,则仅当 dictionary.keys() 包含它时,才会在后台调
我读过这个(来自 here ): User-defined classes have __eq__() and __hash__() methods by default; with them, al
在将功能移植到程序的 Python 3.1 分支时,我遇到了一个奇怪的错误。我将其缩小为以下假设: 与 Python 2.x 相比,在 Python 3.x 中,如果对象具有 __eq__ 方法,则它
我有一个类型,其中相等比较没有意义。明确比较此类型的两个实例的引用或值相等性将指示调用代码中的逻辑错误。 定义 __eq__ 引发异常是不是很糟糕?这有什么陷阱吗?它是否作为某些常见操作的一部分被隐式
我有一个Python程序,其中有一个名为Vector的类,并且该类内部有一个空列表,该列表正在运行时填充。这是初始化: def __init__(self,n): self.vector =
以下代码给出错误信息: class Test(object): def __init__(self, test = 0): self.test = test if __
我还有一个问题要问你。 我有一个带有列表“元信息”的 python 类。此列表包含我的类可能 包含的变量名称。我编写了一个 __eq__ 方法,如果 self 和 other 具有来自 metainf
我正在处理一个集合类,我想为其创建一个 __eq__ 方法。事实证明,它比我想象的要微妙得多,而且我注意到内置集合类的工作方式有几个错综复杂的地方。 真正对我帮助最大的是一个很好的例子。在标准库或任何
假设我有以下程序: class A(object):
为类实现自定义相等函数时,首先检查身份是否有意义?一个例子: def __eq__(self, other): return (self is other) or (other criteri
当我尝试重写魔术方法 __eq__,并使用 super 访问 object 中的基本方法时,出现错误.这不可能是一个错误,但感觉确实像一个错误: class A(object): def __
我遇到了一个问题,我将一个实例添加到一个集合中,然后进行测试以查看该对象是否存在于该集合中。我已经重写了 __eq__() 但在包含测试期间它没有被调用。我是否必须改写 __hash__()?如果是这
在将功能移植到我的程序的 Python 3.1 分支时,我遇到了一个奇怪的错误。我将其缩小到以下假设: 与 Python 2.x 相比,在 Python 3.x 中,如果一个对象具有 __eq__ 方
我是一名优秀的程序员,十分优秀!