语法
object.__ifloordiv__(self, other)
Python__ifloordiv__() 魔法实现了就地除法操作 x //= y ,它计算了整数除法操作 x // y ,并将结果分配给第一个操作数变量x 。这个操作也被称为 增强的算术赋值.该方法只是返回分配给第一个操作数的新值。
- 当你调用
x //= y时,Python 首先尝试调用x.__ifloordiv__(y)。 - 如果没有实现这一点,它就会尝试正常的楼层划分操作
[x.__floordiv__(y)](https://blog.finxter.com/python-__floordiv__-magic-method/ "Python __floordiv__() Magic Method"). - 如果这一点也没有实现,它就会尝试反向地板除法操作
[y.__rfloordiv__(x)](https://blog.finxter.com/python-__rfloordiv__-magic-method/ "Python __rfloordiv__() Magic Method")的操作数交换。
然后将结果赋值给第一个操作数x 。如果这些操作都没有实现,Python 会引发一个TypeError 。
我们把这称为 "Dunder Method",即*"Double UnderscoreMethod"(也称为"Magic Method")*。
重写__ifloordiv__的基本例子
在下面的代码例子中,你创建了一个类Data ,并定义了魔法方法__ifloordiv__(self, other) 。
- "self"参数是每个方法的默认参数,它指的是被调用的对象--在我们的例子中,是就地操作的第一个操作数。
- 就地操作方法的 "其他 "参数指的是第二个操作数,即就地操作中的
yx //= y。
该操作的返回值返回一个假的字符串'finxter 42' ,并分配给第一个操作数。在实践中,这将是就地除法操作的结果。
class Data:
def __ifloordiv__(self, other):
return 'finxter 42'
x = Data()
y = Data()
x //= y
print(x)
# finxter 42
就地除法 //= 没有 __ifloordiv__()
为了支持自定义类上的就地除法,你不必覆盖就地__ifloordiv__() 方法。因为如果这个方法没有被定义,Python将回到正常的 [__floordiv__()](https://blog.finxter.com/python-__floordiv__-magic-method/ "Python __floordiv__() Magic Method")方法,并将其结果分配给第一个操作数。
这里有一个例子
class Data:
def __floordiv__(self, other):
return 'finxter 42'
x = Data()
y = Data()
x //= y
print(x)
# finxter 42
尽管没有定义__ifloordiv__() 方法,但由于__floordiv__() 的 "回退 "魔法方法,原地除法操作x //= y 仍然有效。
就地楼层划分 //= 没有 __ifloordiv__() 和 __floordiv__()
要在一个自定义类上支持就地除法x //= y ,你甚至不需要覆盖任何一个x.__ifloordiv__(y) 或x.__floordiv__(y) 方法。如果这两个方法都没有定义,Python就会返回到反向的 [y.__rfloordiv__(x)](https://blog.finxter.com/python-__rfloordiv__-magic-method/ "Python __rfloordiv__() Magic Method")方法,并将其结果分配给第一个操作数。
这里有一个例子,你为第一个操作数创建了一个不支持楼层除法操作的自定义类。然后你为第二个操作数定义一个自定义类,该类定义了__rfloordiv__() 方法。对于就地操作,Python 返回到在第二个操作数上定义的__rfloordiv__() 方法,并把它赋给第一个操作数x 。
class Data_1:
pass
class Data_2:
def __rfloordiv__(self, other):
return 'finxter 42'
x = Data_1()
y = Data_2()
x //= y
print(x)
# finxter 42
TypeError: //=的操作数类型不支持。
如果你试图执行原地除法x //= y ,但是既没有定义x.__ifloordiv__(y) ,也没有定义x.__floordiv__(y) ,更没有定义y.__rfloordiv(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'
背景底层划分
双反斜线// 操作符执行整数除法,单反斜线/ 操作符执行浮点数除法。整数除法的例子是40//11 = 3 。浮点数除法的例子是40/11 = 3.6363636363636362 。
>>> # Python 3
>>> 40//11
3
>>> 40/11
3.6363636363636362