操作数数据类型 varchar 对于 multiply 运算符无效。_《fluent python》第 13 章 正确重载运算符...

本文探讨了Python和Java中运算符重载的不同处理方式。在Python中,运算符重载允许灵活地处理不同类型的操作,但可能导致一些意外行为,如浮点数的精度问题。而在Java中,由于 BigDecimal 类型不支持中缀运算符,使用大数运算变得复杂。文章详细介绍了Python的运算符重载机制,并强调了遵循鸭子类型的重要性,同时指出不应过度依赖 isinstance() 进行类型检查。
摘要由CSDN通过智能技术生成

269e230fb84f9a9effaf07aa621d00fe.png

引言

有些事情让我不安,比如运算符重载。我决定不支持运算符重载,这完全是个人选择,因为我见过太多 C++ 程序员滥用它——James Gosling(Java 之父)

ps: 运算符重载它不香吗

写在前面

对于复利公式,在python中只需要

interest = principal * ((1 + rate) ** periods - 1)

其中periods是整数, rateinterestprincipal是精确的数字(Python 中decimal.Decimal类的实例)

但是在Java中,如果把float换成精度不定的BigDecimal,就无法再使用中缀运算符,因为中缀运算符只支持基本类型。用过java大数类的都知道会写吐的:

BigDecimal interest = principal.multiply(BigDecimal.ONE.add(rate).pow(periods).subtract(BigDecimal.ONE));

Python禁止重载内置类型的运算符

python支持的运算符

08a2679ae7d1df24566793e8580dd90d.png

一元运算符

  • - (__neg__), 取负运算符
  • + (__pos__), 取正运算符
  • ~ (__invert__), 取反运算符

一元运算符要遵守运算符的一个基本规则:始终返回一个新对象

x+x何时不等

xdecimal.Decimal实例子时,由于+运算返回新的实例,由于计算机存储浮点数的原因可能会导致偏差, 所以导致内容不等, 即x != +x

ps: 一般比较两个浮点数都要设置一个精度来判别

重载加法运算符+和乘法运算符*

为了支持涉及不同类型的运算,Python为中缀运算符特殊方法提供了特殊的分派机制。对 表达式a + b来说,解释器会执行以下几步操作

  • 如果a__add__方法,而且返回值不是NotImplemented,调用a.__add__(b),然后返回结果。
  • 如果a没有__add__方法,或者调用__add__方法返回NotImplemented,检查b有没有__radd__方法,如果有,而且没有返回NotImplemented,调用b.__radd__(a),然后返回结果。
  • 如果b没有__radd__方法,或者调用__radd__方法返回NotImplemented,抛出TypeError,并在错误消息中指明操作数类型不支持。

注意

  • 实现一元运算符和中缀运算符的特殊方法一定不能修改操作数。使用这些运算符的表达式期待结果是新对象
  • 如果由于类型不兼容而导致运算符特殊方法无法返回有效的结果,那么应该返回NotImplemented,而不是抛出 TypeError。返回 NotImplemented 时,另一个操作数所属的类型还有机会执行运算,即Python会尝试调用反向方法。
  • 为了遵守鸭子类型精神,我们不能测试other操作数(即右操作数)的类型,我们要捕获异常,然后返回NotImplemented。如果解释器还未反转操作数,那么它将尝试去做。如果反向方法返回NotImplemented,那么 Python会抛出TypeError,并返回一个标准的错误消息,例如“unsupported operand type(s) for +: Vector and str”。

python3.5支持中缀运算符@(点积运算)

比较运算符

Python解释器对众多比较运算符(==!=><>=<=)的处理与前文类似,不过在两个方面有重大区别。正向和反向调用使用的是同一系列方法。如图所示

3c3420906b6b064efed2c477441bcf5a.png

Python在object基类中通过__ne__方法为!=提供了便利的实现

增量赋值运算符

None

写在最后

我不能体会之前说的少用isinstance()去判断参数类型转而去拥抱鸭子类型,这有什么区别吗?反而我觉得用isinstance()会更显式, 而像鸭子类型那样try...except..反而更隐式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值