Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么调用Python';s';魔术法';与对应运算符的类型转换不一样吗?_Python_Type Conversion_Implicit Conversion_Magic Methods - Fatal编程技术网

为什么调用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'