为什么调用 Python 的 'magic method' 不像对应的运算符那样进行类型转换?
Why does calling Python's 'magic method' not do type conversion like it would for the corresponding operator?
当我从一个整数中减去一个浮点数时(例如 1-2.0
),Python 会进行隐式类型转换(我认为)。但是当我用魔术方法调用我认为是相同的操作时__sub__
,它突然不再了。
我在这里错过了什么?当我为自己的 类 重载运算符时,除了将输入显式转换为我需要的任何类型之外,还有其他解决方法吗?
a=1
a.__sub__(2.)
# returns NotImplemented
a.__rsub__(2.)
# returns NotImplemented
# yet, of course:
a-2.
# returns -1.0
a - b
不仅仅是 a.__sub__(b)
。如果 a
无法处理操作,它还会尝试 b.__rsub__(a)
,在 1 - 2.
的情况下,处理操作的是浮点数 __rsub__
。
>>> (2.).__rsub__(1)
-1.0
你运行a.__rsub__(2.)
,但那是错误的__rsub__
。您需要右侧的 ope运行d 的 __rsub__
,而不是左侧的 ope运行d.
减法运算符中没有内置隐式类型转换。 float.__rsub__
必须手动处理整数。如果您想在自己的运算符实现中进行类型转换,您也必须手动处理。
@user2357112 已经说的很好了,没法举例了[=28=]
class A:
def __sub__(self, other):
print('A.__sub__')
if not isinstance(other, A):
return NotImplemented
return 0
def __rsub__(self, other):
print('A.__rsub__')
if not isinstance(other, A):
return NotImplemented
return 0
class B:
def __sub__(self, other):
print('B.__sub__')
if not isinstance(other, B):
return NotImplemented
return 0
a1 = A()
a2 = A()
b = B()
a1 - a2
A.__sub__
# 0
对象 a1
和 a2
兼容(均为 A
类型),返回有效结果。
接下来考虑,
b - a1
B.__sub__
A.__rsub__
# TypeError: unsupported operand type(s) for -: 'B' and 'A'
对象 b
和 a1
不兼容。首先,b.__sub__
被尝试,returns NotImplemented
,所以 a1.__rsub__
被尝试,returns NotImplemented
。所以引发了 TypeError
。
最后,
a1 - b
A.__sub__
# TypeError: unsupported operand type(s) for -: 'A' and 'B'
这次先尝试a1.__sub__
,即returnsNotImplemented
。现在,由于未定义 b.__rsub__
,因此引发 TypeError
。
当我从一个整数中减去一个浮点数时(例如 1-2.0
),Python 会进行隐式类型转换(我认为)。但是当我用魔术方法调用我认为是相同的操作时__sub__
,它突然不再了。
我在这里错过了什么?当我为自己的 类 重载运算符时,除了将输入显式转换为我需要的任何类型之外,还有其他解决方法吗?
a=1
a.__sub__(2.)
# returns NotImplemented
a.__rsub__(2.)
# returns NotImplemented
# yet, of course:
a-2.
# returns -1.0
a - b
不仅仅是 a.__sub__(b)
。如果 a
无法处理操作,它还会尝试 b.__rsub__(a)
,在 1 - 2.
的情况下,处理操作的是浮点数 __rsub__
。
>>> (2.).__rsub__(1)
-1.0
你运行a.__rsub__(2.)
,但那是错误的__rsub__
。您需要右侧的 ope运行d 的 __rsub__
,而不是左侧的 ope运行d.
减法运算符中没有内置隐式类型转换。 float.__rsub__
必须手动处理整数。如果您想在自己的运算符实现中进行类型转换,您也必须手动处理。
@user2357112 已经说的很好了,没法举例了[=28=]
class A:
def __sub__(self, other):
print('A.__sub__')
if not isinstance(other, A):
return NotImplemented
return 0
def __rsub__(self, other):
print('A.__rsub__')
if not isinstance(other, A):
return NotImplemented
return 0
class B:
def __sub__(self, other):
print('B.__sub__')
if not isinstance(other, B):
return NotImplemented
return 0
a1 = A()
a2 = A()
b = B()
a1 - a2
A.__sub__
# 0
对象 a1
和 a2
兼容(均为 A
类型),返回有效结果。
接下来考虑,
b - a1
B.__sub__
A.__rsub__
# TypeError: unsupported operand type(s) for -: 'B' and 'A'
对象 b
和 a1
不兼容。首先,b.__sub__
被尝试,returns NotImplemented
,所以 a1.__rsub__
被尝试,returns NotImplemented
。所以引发了 TypeError
。
最后,
a1 - b
A.__sub__
# TypeError: unsupported operand type(s) for -: 'A' and 'B'
这次先尝试a1.__sub__
,即returnsNotImplemented
。现在,由于未定义 b.__rsub__
,因此引发 TypeError
。