【发布时间】:2020-06-05 11:57:37
【问题描述】:
我有点头晕,似乎不是只有我一个人,但真的没有解决办法吗?我觉得这很难相信!
所以问题是为什么我不能用 2 个运算符调用 int.__eq__ 或用一个运算符调用 i.__eq__?如何使用__eq__(和其他比较运算符)对整数序列进行逐项比较?
这是来自 python2.7.17 的转储:
>>> i = 0
>>> type(i)
<type 'int'>
>>> i.__eq__(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__eq__'
>>> type(i).__eq__(i, 0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected 1 arguments, got 2
>>> type(i).__eq__(0)
NotImplemented
但是我的 python3.6.9 中的 dumo 表现自己:
>>> i = 0
>>> type(i)
<class 'int'>
>>> i.__eq__(0)
True
>>> type(i).__eq__(i, 0)
True
>>> type(i).__eq__(0) # this is not expected to work, but just for the sake of voodoo.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected 1 arguments, got 0
我知道不再支持 python2,但是有一些应用程序只使用 python2,我想让我的代码向后兼容。
那么任何人都有一个解决方案来破解比较魔术运算符方法作为python2中的函数调用?我确信必须有一些解决方法。
似乎有一些关于此的信息。我刚刚读到 python2 在某些情况下会退回到使用 cmp ,而在 python3 中没有 cmp (或者我读过)。所以我想要做的事情不是使用 eq 和 ne 而是使用 cmp 但我喜欢对此有一些额外的看法
【问题讨论】:
-
注意
int.__eq__实际上是一个绑定方法(实际上是一个method-wrapper),通过将int传递给type.__eq__产生,而不是int定义的未绑定__eq__(就像在 Python 3 中一样)。int.__eq__(int) == True、int.__eq__(float) == False、int.__eq__(3)返回NotImplemented,因为您无法比较类型和int值。 -
(您可以通过比较
type.__eq__.__get__(int, type)和int.__eq__的返回值得到一些提示。我不完全确定int.__eq__实际上会导致type.__eq__.__get__被调用,但两者似乎正在访问或创建method-wrapper的同一实例。) -
好吧,我点击了回答我自己的问题,但它不允许我关闭我的问题。不知道为什么当我没有发布我的答案时。所以我把它放在这里。
-
所以我找到了答案。是的,确实,python2 似乎有理由从魔术比较运算符中转移功能。相反,它使用 cmp 或 cmp。所以解决方案相当简单,而不是优雅。
-
SPECIAL_OPNAMES = \ { 'eq': (lambda *args, **kwargs: not cmp(*args, **kwargs)) \, 'ne ': (lambda *args, **kwargs: cmp(*args, **kwargs)) \ } if sys.version_info.major == 2 else \ {}
标签: python python-2.7 comparison-operators magic-methods