类和对象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 - otherreturn addresult#新类的实例对象,使用加号,调用的重构后加法运算
x = Newint(5)
y = Newint('2')
x + y
3#重构数值方法时,方法中调用了正在重构的数值方法
class Newint2(int):def __add__(self, other):addresult = self - otherreturn addresultdef __sub__(self, other):subresult = self + otherreturn 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 addresultdef __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 addresultdef __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. 当对象是被应用在切片表达式中时,实现整形强制转换 |
类和对象8:数值方法相关推荐
- C++ 笔记(18)— 类和对象(this 指针、指向类的指针、类静态成员变量和函数)
1. this 指针 在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址. this 指针是所有成员函数的隐含参数.因此,在成员函数内部,它可以用来指向调用对象. 友元函数没有 thi ...
- C++ 笔记(16)— 类和对象(类定义、类实例对象定义、访问类成员、类成员函数、类 public/private/protected 成员、类对象引用和指针)
1. 类的定义 类定义是以关键字 class 开头,后跟类的名称.并在它后面依次包含类名,一组放在 {} 内的成员属性和成员函数,以及结尾的分号. 类声明将类本身及其属性告诉编译器.类声明本身并不能改 ...
- C02-程序设计基础提高班(C++)第9周上机任务-类和对象
第9周:阅读教材第8章(p231-262),主要内容是类和对象,学会定义类和对象解决问题,完成第9周上机任务: (回到C02-程序设计基础提高班(C++)学习安排) 实践任务: [任务1]阅读.运行下 ...
- 函数返回类的对象与拷贝构造函数
C++中,如果我们在一个函数中,定义了一个类的对象,然后返回这个对象,在main函数中用一个对象去接受这个返回的对象的时候,这里面参与的函数调用大家可能不熟悉,这里通过程序和注释的方式给大家讲解一下. ...
- ZJU-java进阶笔记 第一、二周(类与对象,对象交互)
对象变量是对象的管理者,而非所有者 VendingMachine vm = new VendingMachine(); this指代当前对象 成员函数可以直接(不需要点运算符)调用本类的其他成员函数 ...
- 3个题目熟悉类和对象基础
1.按要求编写Java应用程序: (1)编写西游记人物类(XiYouJiRenWu)其中属性有:身高(height),名字(name),武器(weapon)方法有:显示名字(printName),显示 ...
- 刻意练习:Python基础 -- Task10. 类与对象
背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...
- java中具有继承关系的类及其对象初始化顺序
先说结论 对于具有继承关系的类,它们的类和对象构造顺序为:父类的类构造器() -> 子类的类构造器() -> 父类成员变量的赋值和实例代码块 -> 父类的构造函数 -> 子类成 ...
- python的类和对象_Python类与对象实验
一.任务描述 本实验任务主要对Python类与对象进行一些基本操作,通过完成本实验任务,要求学生熟练掌握Python类与对象的关系,并对Python类与对象的基本操作进行整理并填写工作任务报告. 二. ...
- 简单介绍实体类或对象序列化时,忽略为空属性的操作
这篇文章主要介绍了实体类或对象序列化时,忽略为空属性的操作,具有很好的参考价值,希望对大家有所帮助.如有错误或未考虑完全的地方,望不吝赐教 第一种,在配置文件配置 在application.xml直接 ...
最新文章
- eeglab中文教程系列(7)-数据叠加平均{2}绘制2D和3D图
- Python基础 基本数据类型
- 【Chocolatey】查找包
- nginx 端口转发
- js- 引用和复制(传值和传址)
- 【转载】Sqlserver使用Convert函数进行数据类型转换
- 按键精灵一个命令学会这么厉害
- 小说网站系统源码|PHP付费小说网站源码带app
- Eviews操作笔记自用(横截面数据)
- JavaScript设计模式之装饰者模式
- 太阳山采风(部分稿件)
- 激光测距芯片VL53L0X的使用与代码
- 自建 IPA 分发平台
- 医院信息化系统大全?
- 网络安全学习路线(顶级白帽黑客)
- 绝佳的3Dmax渲染技巧,这些精美的效果让人称赞不已!速看
- 第十一届蓝桥杯大赛决赛赛题 C++ 大学C组
- springboot项目中访问不到html页面问题
- 倍思和绿联扩展坞哪个好_Macbook用什么扩展坞好?贝尔金对比绿联,国产更胜一筹...
- 抱抱脸(hugging face)教程-中文翻译-模型概要