python - 当 __hash__ 和 __eq__ 在没有参数的情况下不可调用时,Python 的 dict 如何将类型管理为键?
问题描述
Python 文档指出 dict 键必须是可散列的,这意味着具有__hash__
和__eq__
我试图了解在 dict 中使用类型作为键是如何工作的,至少在默认情况下,这两种方法都需要一个实例作为第一个参数。
考虑下面的代码及其输出:
class Apple:
pass
class Orange:
pass
lookup = {Apple: lambda: print('Apple!'), Orange: lambda: print('Orange!')}
try:
print(Apple.__hash__())
except Exception as e:
print(e)
try:
print(Apple.__eq__())
except Exception as e:
print(e)
an_apple = Apple()
an_orange = Orange()
lookup[type(an_apple)]()
lookup[type(an_orange)]()
descriptor '__hash__' of 'object' object needs an argument
descriptor '__eq__' of 'object' object needs an argument
Apple!
Orange!
dict 如何获取哈希和检查类型的相等性?
解决方案
Python 不会在实例上查找魔术方法。它在班级本身上查找它们。在你的情况下,类是。Apple
type
>>> class Apple: pass
...
>>> hash(Apple)
5929200437980
>>> type.__hash__(Apple)
5929200437980
同样的事情发生在__eq__
. 如果您尝试将魔术方法附加到实例而不是类,也可以看到这一点。
>>> class Apple:
... def __hash__(self):
... return 1
...
>>> my_apple = Apple()
>>> my_apple.__hash__ = lambda: 2
>>> hash(my_apple) # 1, not 2
1
>>> my_apple.__hash__()
2
>>> Apple.__hash__(my_apple)
1
请注意,Apple
两者my_apple
都__hash__
定义了它们,但调用的是类的方法,而不是实例上的方法。
推荐阅读
- adafruit - LoRa 范围 - 发送数据
- python - 需要修改我的正则表达式来捕捉本质上相同句子的不同表示
- wordpress - 如何将我的 divi 网站转换为子主题?
- python - Python 在一组序列中提取长度为 X 的常见模式
- pine-script - 满足交叉条件时的红色圆圈
- java - Android Studio Gradle Sync:“无法加载类...”
- android - 在物理设备崩溃 android studio flutter 上构建 Apk
- javascript - Chart.js:如果差异太大,某些部门未显示
- python-3.x - 无法在 React Native 中通过 FAST api 发送图像。在 FAST api 后端收到错误 422
- angular - 在组件中绑定 formControlName | 可选用法