为什么调用Python';s';魔术法';与对应运算符的类型转换不一样吗?
当我从一个整数中减去一个浮点数时(例如,为什么调用Python';s';魔术法';与对应运算符的类型转换不一样吗?,python,type-conversion,implicit-conversion,magic-methods,Python,Type Conversion,Implicit Conversion,Magic Methods,当我从一个整数中减去一个浮点数时(例如,1-2.0),Python会进行隐式类型转换(我想)。但是,当我使用神奇的方法调用我认为是相同的操作时,它突然不再是了 我错过了什么?当我为自己的类重载运算符时,除了显式地将输入强制转换为我需要的任何类型之外,还有其他方法吗 a=1 a.__sub__(2.) # returns NotImplemented a.__rsub__(2.) # returns NotImplemented # yet, of course: a-2. # returns -
1-2.0
),Python会进行隐式类型转换(我想)。但是,当我使用神奇的方法调用我认为是相同的操作时,它突然不再是了
我错过了什么?当我为自己的类重载运算符时,除了显式地将输入强制转换为我需要的任何类型之外,还有其他方法吗
a=1
a.__sub__(2.)
# returns NotImplemented
a.__rsub__(2.)
# returns NotImplemented
# yet, of course:
a-2.
# returns -1.0
a-b
不仅仅是a.\uu sub\uuu(b)
。如果a
不能处理该操作,它也会尝试b.\uuuu rsub\uuuu(a)
,在1-2.
情况下,处理该操作的是浮点的\uu rsub\uuu
>>> (2.).__rsub__(1)
-1.0
您运行了a.\uuuursub\uuuuuuu2.
,但这是错误的\uuursub\uuuuuuuuu
。您需要的是右侧操作数的\uuuu rsub\uuu
,而不是左侧操作数
减法运算符中没有内置的隐式类型转换<代码>浮动。必须手动处理整数。如果您希望在自己的运算符实现中进行类型转换,您也必须手动处理。@user2357112已经说得很好,但没有一个类似的示例
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
和a2
是兼容的(都是A
),将返回有效结果
接下来,考虑,
b - a1
B.__sub__
A.__rsub__
# TypeError: unsupported operand type(s) for -: 'B' and 'A'
对象b
和a1
不兼容。首先,b.\uuuuu sub\uuuu
被尝试,它返回NotImplemented
,因此a1.\uuuu rsub\uuuuu
被尝试,它也返回NotImplemented
。因此产生了一个TypeError
最后,
a1 - b
A.__sub__
# TypeError: unsupported operand type(s) for -: 'A' and 'B'
这一次,首先尝试
a1.\uuuuu sub\uuuu
,返回NotImplemented
。现在,由于没有定义b.\uuuuu rsub\uuuuuuuu
,因此产生了TypeError
。值得注意的是,问题中调用返回的NotImplemented
结果是尝试反向方法的信号。谢谢!我知道它会尝试\uuuu rsub\uuuu
,但不知道它会反转参数顺序。@doppler:让左操作数同时处理\uuuu sub\uuuu
和\uuu rsub\uuuu
是毫无意义的。这将是两个具有完全相同作业的方法,正确的操作数将没有机会提供实现。@doppler:no.self.other-self调用
,如果other
无法处理它。调用other.\uuuuu sub\uuuuu(self)
将毫无意义。我们已经知道,other
无法处理它。@user2357112我的理解是,当两个two.\uuuuu rsub\uuuuu(一)
和one.\uuuu sub\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,
a1 - b
A.__sub__
# TypeError: unsupported operand type(s) for -: 'A' and 'B'