加入收藏 | 设为首页 | 会员中心 | 我要投稿 唐山站长网 (https://www.0315zz.com.cn/)- 数据安全、数据开发、文字识别、图像处理、媒体智能!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

加速向数字化转型

发布时间:2021-02-13 10:30:00 所属栏目:外闻 来源:互联网
导读:推广到其它二元运算 解决掉了减法运算,那么其它二元运算又如何呢?好吧,事实证明它们的操作相同,只是碰巧使用了不同的特殊/魔术方法名称。 所以,如果我们可以推广这种方法,那么我们就可以实现 13 种操作的语义:+ 、-、*、@、/、//、%、**、、、、^、和

推广到其它二元运算

解决掉了减法运算,那么其它二元运算又如何呢?好吧,事实证明它们的操作相同,只是碰巧使用了不同的特殊/魔术方法名称。

所以,如果我们可以推广这种方法,那么我们就可以实现 13 种操作的语义:+ 、-、*、@、/、//、%、**、<<、>>、&、^、和 |。

由于闭包和 Python 在对象自省上的灵活性,我们可以提炼出 operator 函数的创建。

 

4、子类优先于父类

如果你看一下__rsub__() 的文档,就会注意到一条注释。它说如果一个减法表达式的右侧是左侧的子类(真正的子类,同一类的不算),并且两个对象的__rsub__() 方法不同,则在调用__sub__() 之前会先调用__rsub__()。换句话说,如果 b 是 a 的子类,调用的顺序就会被颠倒。

这似乎是一个很奇怪的特例,但它背后是有原因的。当你创建一个子类时,这意味着你要在父类提供的操作上注入新的逻辑。这种逻辑不一定要加给父类,否则父类在对子类操作时,就很容易覆盖子类想要实现的操作。

具体来说,假设有一个名为 Spam 的类,当你执行 Spam() - Spam() 时,得到一个 LessSpam 的实例。接着你又创建了一个 Spam 的子类名为 Bacon,这样,当你用 Spam 去减 Bacon 时,你得到的是 VeggieSpam。

如果没有上述规则,Spam() - Bacon() 将得到 LessSpam,因为 Spam 不知道减掉 Bacon 应该得出 VeggieSpam。

但是,有了上述规则,就会得到预期的结果 VeggieSpam,因为 Bacon.__rsub__() 首先会在表达式中被调用(如果计算的是 Bacon() - Spam(),那么也会得到正确的结果,因为首先会调用 Bacon.__sub__(),因此,规则里才会说两个类的不同的方法需有区别,而不仅仅是一个由 issubclass() 判断出的子类。)

 

2、让右侧使用__rsub__()

但是,如果 a 没有实现__sub__() 怎么办?如果 a 和 b 是不同的类型,那么我们会尝试调用 b 的 __rsub__()(__rsub__ 里面的“r”表示“右”,代表在操作符的右侧)。

当操作的双方是不同类型时,这样可以确保它们都有机会尝试使表达式生效。当它们相同时,我们假设__sub__() 就能够处理好。但是,即使两边的实现相同,你仍然要调用__rsub__(),以防其中一个对象是其它的(子)类。

3、不关心类型

现在,表达式双方都可以参与运算!但是,如果由于某种原因,某个对象的类型不支持减法怎么办(例如不支持 4 - “stuff”)?在这种情况下,__sub__ 或__rsub__ 能做的就是返回 NotImplemented。

这是给 Python 返回的信号,它应该继续执行下一个操作,尝试使代码正常运行。对于我们的代码,这意味着需要先检查方法的返回值,然后才能假定它起作用。


(编辑:唐山站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读