Python的__sub__()魔法方法

1,028 阅读4分钟

语法

object.__sub__(self, other)

Python的object.__sub__(self, other) 方法返回一个新的对象,代表两个对象的差值。它实现了Python中的减法运算符 -

我们称它为*"* Dunder方法",意思是*" 下划线方法"(也叫"魔术方法")*。要获得所有带有解释的Dunder方法的列表,请查看我们博客上的Dunder小抄文章

例子

a-b 在下面的例子中,你创建了一个自定义类Data ,并覆盖了__sub__() 方法,从而创建了一个新的Data 对象,其值是两个操作数ab 的差值Data

class Data:

    def __init__(self, value):
        self.value = value
        
    def __sub__(self, other):
        return Data(self.value - other.value)


a = Data(44)
b = Data(2)
c = a - b

print(c.value)
# 42

你已经定义了dunder方法,所以产生的两个Data 对象的差值本身就是一个Data 对象。

print(type(c))
# <class '__main__.Data'>

如果你没有定义__sub__() 方法,Python 会提出一个TypeError

考虑下面的代码片段,你试图在没有定义dunder方法的情况下减去两个自定义对象__sub__()

class Data:

    def __init__(self, value):
        self.value = value


a = Data(44)
b = Data(2)
c = a - b

在我的电脑上运行这个导致了以下错误信息。

Traceback (most recent call last):
  File "C:\Users\xcent\Desktop\code.py", line 9, in <module>
    c = a - b
TypeError: unsupported operand type(s) for -: 'Data' and 'Data'

这个错误的原因是,__sub__() dunder方法从未被定义过,而且默认情况下没有为自定义对象定义该方法。因此,为了解决TypeError: unsupported operand type(s) for - ,你需要在你的类定义中提供__sub__(self) 方法,如前所示。

class Data:

    def __init__(self, value):
        self.value = value
        
    def __sub__(self, other):
        return Data(self.value - other.value)

相关视频

高级示例--设置差值重写

要在自定义对象上使用减法运算符 ,请定义__sub__() dunder方法,该方法需要两个参数:selfother ,并返回self - other 的结果。你可以通过使用该对象中维护的属性(数据)来定义具体行为。

在下面的代码中,你从{'coffee', 'banana', 'bred'} 中创建了一个篮子,但随后你又从其中删除了另一个篮子{'bred'} 中的内容--例如为了防止重复购买。

class Basket:
    def __init__(self, goods):
        self.goods = goods

    def __sub__(self, other):
        return Basket(self.goods - other.goods)

my_basket = Basket({'coffee', 'banana', 'bred'})
to_remove = Basket({'bred'})

updated_basket = my_basket - to_remove
print(updated_basket.goods)

这个代码片段的输出是新的篮子。

{'banana', 'coffee'}

该代码由以下步骤组成。

  • 创建持有列表内容的类Basket ,以存储一些商品。
  • 定义神奇的方法__sub__ ,通过合并两个操作者的篮子中的商品集来创建一个新的篮子。注意,我们依靠已经实现的对集合的减法运算,即集合差,来实际实现篮子的减法运算。
  • 我们创建了两个篮子my_basketto_remove ,并计算它们之间的差值,得到一个新的篮子updated_basket

Python的__sub__与__isub__比较

Python提供了操作符x -= y ,通过计算差值x - y ,并将结果分配给第一个操作数的变量名x ,来就地减去两个对象 。你可以通过在你的类定义中覆盖神奇的 "dunder "方法__isub__(self, other) ,为你自己的类设置就地减法行为。

>>> x = 3
>>> x -= 2
>>> x
1

表达式x -= y 是较长形式的x = x - y 的语法糖。

>>> x = 3
>>> x = x - 2
>>> x
1

因此,__sub____isub__ 方法之间的区别如下。

如果你覆盖了Python dunder__sub__ 方法,你将定义计算的结果a - b 。如果你覆盖了Python dunder__isub__ 方法,你将定义计算的结果a =- b ,它修改了第一个操作数a ,而不是返回一个新对象。换句话说,前者的操作符是 减法,而后者是就地减法操作符。

从哪里开始?

理论够多了,让我们来实践一下吧!

要想在编码方面取得成功,你需要走出去,为真正的人解决真正的问题。这样你才能轻松成为六位数的收入者。而这也是你如何在实践中打磨出你真正需要的技能。毕竟,学习没有人需要的理论有什么用?

实践项目就是你在编码中磨练你的锯子的方法!

你想通过专注于实际的代码项目,成为一个代码大师,真正为你挣钱,为人们解决问题吗?

那就成为一名Python自由开发者吧!这是接近提高Python技能任务的最好方式--即使你是一个完全的初学者。

参加我的免费网络研讨会"如何建立你的高收入技能Python",看看我是如何在网上发展我的编码业务的,你也可以这样做--从你自己家里的舒适度。

现在就参加免费网络研讨会

The postPython __sub__() Magic Method首次出现在Finxter上。