类和对象8:数值方法

目录

1. 数值方法概述

2. 二元运算:正运算

3. 右侧二元运算:反运算

4. 增量二元运算

5. 一元运算

6. 类型转换


1. 数值方法概述

Python 2.2 之后,对类和类型进行了统一,int()、float()、str()、list()、tuple()等都由内置函数变为了工厂函数,也即类对象;

因此,在 Python 中的各种赋值操作,实际上是创建相应的实例对象,各种数值间的操作也就相当于调用实例对象的各种方法;

Python 内置了类对象的数值魔法方法,可以通过重构这些数值方法,自定义任何对象间的数值运算、操作。

#通常内置函数(BIF)类型如下
type(len)
<class 'builtin_function_or_method'>

#工厂函数类型如下,为类对象
type(int)
<class 'type'>

#x、y的赋值实际上是创建类对象 int 的实例对象的过程
x = int('1')
y = int(1.1)

#x、y的加法运算,即使用了类对象内置的数值方法
x + y
2

2. 二元运算:正运算

Python 中二元运算,即正运算的数值方法中如下表:

魔法方法

含义

__add__(self, other)

定义加法的行为:+

__sub__(self, other)

定义减法的行为:-

__mul__(self, other)

定义乘法的行为:*

__truediv__(self, other)

定义真除法的行为:/

__floordiv__(self, other)

定义整数除法的行为://

__mod__(self, other)

定义取模算法的行为:%

__divmod__(self, other)

定义当被 divmod() 调用时的行为

__pow__(self, other[, modulo])

定义当被 power() 调用或 ** 运算时的行为

__lshift__(self, other)

定义按位左移位的行为:<<

__rshift__(self, other)

定义按位右移位的行为:>>

__and__(self, other)

定义按位与操作的行为:&

__xor__(self, other)

定义按位异或操作的行为:^

__or__(self, other)

定义按位或操作的行为:|

正运算,即给出的参数从左至右参与运算符运算,如 __add__(self, other),即定义了 self + other 的数值运算;

需要注意的是,重构数值方式时,方法中不要直接调用正在重构的数值方法,可能会导致无限递归错误;

#基于 int 创建一个新的类,重构加法运算
class Newint(int):
     def __add__(self, other):
         addresult = self - other
         return addresult
  
#新类的实例对象,使用加号,调用的重构后加法运算   
x = Newint(5)
y = Newint('2')
x + y
3

#重构数值方法时,方法中调用了正在重构的数值方法
class Newint2(int):
     def __add__(self, other):
         addresult = self - other
         return addresult
     def __sub__(self, other):
         subresult = self + other
         return subresult
     
#新类的实例对象,调用加法触发无限递归
x = Newint2(0)
y = Newint2(1)
x + y
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 3, in __add__
  File "<input>", line 6, in __sub__
  File "<input>", line 3, in __add__
  File "<input>", line 6, in __sub__
……
  File "<input>", line 3, in __add__
  File "<input>", line 6, in __sub__
RecursionError: maximum recursion depth exceeded

#重构数值方法时,如方法中需要调用被重构的数值方法
#将数值运算所调用的参数,重新创建为非当前类(如下例子中使用父类 int)的实例对象
class Newint2(int):
     def __add__(self, other):
         addresult = int(self) - int(other)
         return addresult
     def __sub__(self, other):
         subresult = int(self) + int(other)
         return subresult
     
#新类的实例对象,调用重构的数值方法,运算正常
x = Newint2(0)
y = Newint2(1)
x + y
-1
x - y
1

3. 右侧二元运算:反运算

Python 中右侧二元运算,即反运算的数值方法中如下表:

魔法方法

含义

__radd__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

__rsub__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

__rmul__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

__rtruediv__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

__rfloordiv__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

__rmod__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

__rdivmod__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

__rpow__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

__rlshift__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

__rrshift__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

__rand__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

__rxor__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

__ror__(self, other)

(与上方相同,当左操作数不支持相应的操作时被调用)

这些方法是前一节中二元运算的右侧副本,有着相同的参数表和计算方法,但是从右侧开始调用参数;

反运算,给出的参数从右至左参与运算符运算,如 __radd__(self, other),即定义了 other + self 的数值运算;

反运算方法,只有当实例对象在运算符右侧,且运算符左侧不是执行该运算的类的一个实例对象时调用;

具体应该在何时使用正运算,何时使用反运算如下:

  • instance + instance 运行 __add__
  • instance + noninstance 运行 __add__
  • noninstance + instance 运行 __radd__
#创建类,重构加法和反加法
class Newint(int):
     def __add__(self, other):
         addresult = (int(self) + int(other)) * 10 
         return addresult
     def __radd__(self, other):
         raddresult = (int(self) + int(other)) // 10 
         return raddresult

#instance + instance 运行 __add__
x + y
130

#instance + noninstance 运行 __add__
x + 5
130

#noninstance + instance 运行 __radd__
8 + y
1

4. 增量二元运算

Python 中增量二元运算的数值方法中如下表:

魔法方法

含义

__iadd__(self, other)

定义赋值加法的行为:+=

__isub__(self, other)

定义赋值减法的行为:-=

__imul__(self, other)

定义赋值乘法的行为:*=

__itruediv__(self, other)

定义赋值真除法的行为:/=

__ifloordiv__(self, other)

定义赋值整数除法的行为://=

__imod__(self, other)

定义赋值取模算法的行为:%=

__ipow__(self, other[, modulo])

定义赋值幂运算的行为:**=

__ilshift__(self, other)

定义赋值按位左移位的行为:<<=

__irshift__(self, other)

定义赋值按位右移位的行为:>>=

__iand__(self, other)

定义赋值按位与操作的行为:&=

__ixor__(self, other)

定义赋值按位异或操作的行为:^=

__ior__(self, other)

定义赋值按位或操作的行为:|=

增量二元方法,要同时执行二元运算和赋值,需要在方法中执行操作(修改 self)和返回结果(可能是self);

此外,调用增量二元方法时,还需要考虑二元正运算和反运算。

5. 一元运算

魔法方法

含义

_pos__(self)

定义正号的行为:+x

__neg__(self)

定义负号的行为:-x

__abs__(self)

定义当被 abs() 调用时的行为

__invert__(self)

定义按位求反的行为:~x

6. 类型转换

魔法方法

含义

__complex__(self)

定义当被 complex() 调用时的行为(需要返回恰当的值)

__int__(self)

定义当被 int() 调用时的行为(需要返回恰当的值)

__float__(self)

定义当被 float() 调用时的行为(需要返回恰当的值)

__round__(self[, n])

定义当被 round() 调用时的行为(需要返回恰当的值)

__index__(self)

1. 当对象是被应用在切片表达式中时,实现整形强制转换
2. 如果你定义了一个可能在切片时用到的定制的数值型,你应该定义 __index__
3. 如果 __index__ 被定义,则 __int__ 也需要被定义,且返回相同的值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

燃烧的火鸟啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值