• 类和对象8:数值方法


    目录

    1. 数值方法概述

    2. 二元运算:正运算

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

    4. 增量二元运算

    5. 一元运算

    6. 类型转换


    1. 数值方法概述

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

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

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

    1. #通常内置函数(BIF)类型如下
    2. type(len)
    3. <class 'builtin_function_or_method'>
    4. #工厂函数类型如下,为类对象
    5. type(int)
    6. <class 'type'>
    7. #x、y的赋值实际上是创建类对象 int 的实例对象的过程
    8. x = int('1')
    9. y = int(1.1)
    10. #x、y的加法运算,即使用了类对象内置的数值方法
    11. x + y
    12. 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 的数值运算;

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

    1. #基于 int 创建一个新的类,重构加法运算
    2. class Newint(int):
    3. def __add__(self, other):
    4. addresult = self - other
    5. return addresult
    6. #新类的实例对象,使用加号,调用的重构后加法运算
    7. x = Newint(5)
    8. y = Newint('2')
    9. x + y
    10. 3
    11. #重构数值方法时,方法中调用了正在重构的数值方法
    12. class Newint2(int):
    13. def __add__(self, other):
    14. addresult = self - other
    15. return addresult
    16. def __sub__(self, other):
    17. subresult = self + other
    18. return subresult
    19. #新类的实例对象,调用加法触发无限递归
    20. x = Newint2(0)
    21. y = Newint2(1)
    22. x + y
    23. Traceback (most recent call last):
    24. File "<input>", line 1, in <module>
    25. File "<input>", line 3, in __add__
    26. File "<input>", line 6, in __sub__
    27. File "<input>", line 3, in __add__
    28. File "<input>", line 6, in __sub__
    29. ……
    30. File "<input>", line 3, in __add__
    31. File "<input>", line 6, in __sub__
    32. RecursionError: maximum recursion depth exceeded
    33. #重构数值方法时,如方法中需要调用被重构的数值方法
    34. #将数值运算所调用的参数,重新创建为非当前类(如下例子中使用父类 int)的实例对象
    35. class Newint2(int):
    36. def __add__(self, other):
    37. addresult = int(self) - int(other)
    38. return addresult
    39. def __sub__(self, other):
    40. subresult = int(self) + int(other)
    41. return subresult
    42. #新类的实例对象,调用重构的数值方法,运算正常
    43. x = Newint2(0)
    44. y = Newint2(1)
    45. x + y
    46. -1
    47. x - y
    48. 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__
    1. #创建类,重构加法和反加法
    2. class Newint(int):
    3. def __add__(self, other):
    4. addresult = (int(self) + int(other)) * 10
    5. return addresult
    6. def __radd__(self, other):
    7. raddresult = (int(self) + int(other)) // 10
    8. return raddresult
    9. #instance + instance 运行 __add__
    10. x + y
    11. 130
    12. #instance + noninstance 运行 __add__
    13. x + 5
    14. 130
    15. #noninstance + instance 运行 __radd__
    16. 8 + y
    17. 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__ 也需要被定义,且返回相同的值

  • 相关阅读:
    1.3 - 码制
    带你看懂 HMR 热更新原理
    vcenter异常死机无法重启
    基于pytorch使用LSTM实现文本匹配任务
    Web大学生网页作业成品:基于html制作中国科技发展网站设计题材【航天之路7页】HTML+CSS+JavaScript
    乌克兰的 IT 外包,为什么如此“发达”?
    矩阵理论复习(三)
    SecureCRT (Mac/Windows)中文---远程连接与管理的安全新选择
    时间同步NTP
    java中volatile解决可见性和有序性问题
  • 原文地址:https://blog.csdn.net/davidksatan/article/details/125569937