如何实现满足特定对象等价条件的整数返回函数f?
一、需求
能否编写一个函数f,满足:
- 接收单个参数作为输入
- 返回整数
- 满足
f(x) == f(y)当且仅当x与y完全相同,或x是y的副本。
我们定义“x与y完全相同,或x是y的副本”为满足以下至少一个条件:
id(x) == id(y)返回Truerepr(x) == repr(y)返回Truex is y返回Truey is x返回Truex == copy.deepcopy(y)返回Truey == copy.deepcopy(x)返回True
需假设无人定义异常的__eq__、__copy__或__deepcopy__()方法。
二、函数
f的一种实现尝试 我初步实现函数f如下:
pi = lambda k_1, k_2: (1/2)*(k_1 + k_2)*(k_1 + k_2 + 1)+k_2 def f(x:object) -> int: """ Based on something called "Cantor's pairing function" from the field of mathematics. """ k_1 = hash(x) k_2 = hash(type(x)) if k_1 < 0 or k_2 < 0: raise NotImplementedError() return pi(k_1, k_2)
三、现有实现的缺陷
存在以下问题:
- 不同对象可能有相同哈希值,例如
hash([1, 2])可能等于hash([2, 3]) - 仅当
hash()返回非负整数时才能正常工作
四、
id(x) == id(y)与x == y的区别 x == y由x.__eq__(y)实现。注意对象的id通常与其副本的id不同,二者内存地址不同。
以下代码展示__eq__()与id()的区别:
x = [1, 2, 3] y = [1, 2, 3] print("id(x)".ljust(15), id(x)) print("id(y)".ljust(15), id(y)) print("x is x".ljust(15), x is x) print("x is y".ljust(15), x is y) print("x == x".ljust(15), x == x) print("x == y".ljust(15), x == y)
输出结果:
id(x) 2531180442688 id(y) 2531180443264 x is x True x is y False x == x True x == y True
五、关于自定义
__repr__或__eq__的顾虑 需假设无人定义异常的__eq__、__hash__方法。例如理论上可定义如下类:
import random class NoNoNo: def __init__(self, *args): self.myVal = random.randint(1, 9) def __eq__(self, other): return False def __repr__(self): return "$"
该类实例永远互不相等:
import copy x = NoNoNo() y = copy.deepcopy(x) print("x == y?", "Yes" if x == y else "No") # prints "x == y? No"
且repr(x)与repr(y)始终相同:
import copy x = NoNoNo() y = NoNoNo() # `y` IS VERY DIFFERENT FROM `x` print("repr(x) == repr(y)?", "Yes" if repr(x) == repr(y) else "No") # prints "repr(x) == repr(y)? Yes"
内容的提问来源于stack exchange,提问作者Toothpick Anemone
相关产品推荐
相关产品推荐

