语法
object.__itruediv__(self, other)
Python__itruediv__() 魔法实现了原地除法运算 x /= y ,它计算除法运算 x / y ,并将结果分配给第一个操作数变量x 。这个操作也被称为 增强的算术赋值.该方法只是返回要分配给第一个操作数的新值。
- 当你调用
x /= y时,Python 首先尝试调用x.__itruediv__(y)。 - 如果没有实现这一点,它会尝试正常的真除法操作
[x.__truediv__(y)](https://blog.finxter.com/python-__truediv__-magic-method/ "Python __truediv__() Magic Method"). - 如果这一点也没有实现,它将尝试反向真除法操作
[y.__rtruediv__(x)](https://blog.finxter.com/python-__rtruediv__-magic-method/ "Python __rtruediv__() Magic Method")与互换的操作数。
然后将结果赋值给第一个操作数x 。如果这些操作都没有实现,Python 会引发一个TypeError 。
我们把这称为 "Dunder Method",即*"Double UnderscoreMethod"(也称为"Magic Method")*。
重写__itruediv__的基本例子
在下面的代码例子中,你创建了一个类Data ,并定义了魔法方法__itruediv__(self, other) 。
- "self"参数是每个方法的默认参数,它指的是被调用的对象--在我们的例子中是原地操作的第一个操作数。
- 就地操作方法的 "其他 "参数指的是第二个操作数,即就地操作中的
yx /= y。
该操作的返回值返回一个假的字符串'finxter 42' ,并分配给第一个操作数。在实践中,这将是原地真除法操作的结果。
class Data:
def __itruediv__(self, other):
return 'finxter 42'
x = Data()
y = Data()
x /= y
print(x)
# finxter 42
原地真除法 /= 没有 __itruediv__()
要在一个自定义类上支持原地真除法,你不必覆盖原地__itruediv__() 方法。因为如果这个方法没有被定义,Python将回到正常的 [__truediv__()](https://blog.finxter.com/python-__truediv__-magic-method/ "Python __truediv__() Magic Method")方法,并将其结果分配给第一个操作数。
这里有一个例子。
class Data:
def __truediv__(self, other):
return 'finxter 42'
x = Data()
y = Data()
x /= y
print(x)
# finxter 42
尽管没有定义__itruediv__() 方法,但由于__truediv__() "回退 "魔法方法,原地的位数左移操作x /= y 仍然有效!
没有__itruediv__()和__truediv__()的就地真除法/=。
要在一个自定义类上支持原地真除法x /= y ,你甚至不需要覆盖任何一个x.__itruediv__(y) 或x.__truediv__(y) 方法。如果这两个方法都没有被定义,Python会回到反向的 [y.__rtruediv__(x)](https://blog.finxter.com/python-__rtruediv__-magic-method/ "Python __rtruediv__() Magic Method")方法,并将其结果分配给第一个操作数。
这里有一个例子,你为第一个操作数创建一个不支持真除法操作的自定义类。然后你为第二个操作数定义了一个自定义类,该类定义了__rtruediv__() 方法。对于原地操作,Python 返回到在第二个操作数上定义的__rtruediv__() 方法,并把它赋给第一个操作数x 。
class Data_1:
pass
class Data_2:
def __rtruediv__(self, other):
return 'finxter 42'
x = Data_1()
y = Data_2()
x /= y
print(x)
# finxter 42
TypeError: /=的操作数类型不支持。
如果你试图执行原地除法x /= y ,但是既没有定义x.__itruediv__(y) ,也没有定义x.__truediv__(y) ,更没有定义y.__rtruediv(x) ,Python 会引发一个 "TypeError: unsupported operand type(s) for /="。要解决这个错误,只需在执行原地操作之前定义这些方法中的任何一个。
class Data:
pass
x = Data()
y = Data()
x /= y
输出
Traceback (most recent call last):
File "C:\Users\xcent\Desktop\code.py", line 8, in <module>
x /= y
TypeError: unsupported operand type(s) for /=: 'Data' and 'Data'
背景真实除法
在Python 3中,单个前斜杠"/"是一个 float除法操作符,它的结果是返回一个浮点数。例如,表达式10/4 返回2.5 而不是2 ,4/2 返回2.0 而不是2 。
>>> # Python 3
>>> 10/4
2.5
>>> 4/2
2.0
要注意使用最新的Python类型。例如,Python 2.0为/ 算子返回一个整数,而不是一个浮点数。另外,当我们在Python中执行除法时,我们要注意除以什么值。我们发现,如果我们除以一个整数,它就会四舍五入 为一个整数。
>>> 10 / 90
0