python比较运算符重载_Python小白高阶: 运算符重载

本章重点内容:

1、基础知识

2、索引和分片:__getitem__和__setitem__

3、索引迭代:__getitem__

4、可迭代对象:__iter__和__next__

5、属性访问:__getattr__和__setattr__

6、字符串显示:__repr__和__str__

7、右侧加法和原位置加法:__radd__和__iadd__

8、调用表达式:__call__

9、比较运算:__lt__、__gt__和其他方法

10、布尔测试:__bool__和__len__

11、对象析构函数:__del__

接下来针对以上内容进行详细的说明,如下:

1、基础知识

运算符重载,意味着在某个类的方法中拦截内置的操作,当类的实例出现在内置操作中时,Python会自动调用你的方法,并且你的方法的返回值会作为相应操作的结果,

1)运算符重载让类拦截常规的Python操作

2)类可重载所有Python表达式运算符

3)类也可重载打印、函数调用、属性访问等内置运算

4)重载使类实例的行为更接近内置类型

5)重载是通过在一个类中提供特殊名称的方法来实现的

我们通过一个简单的例子来看下构造函数(__init__)和表达式(__sub__)的运算符重载,来理解上面的内容,具体代码如下:

常见的运算符重载方法还有很多,接下来择取重点且常见的说明,至于有哪些或者多少运算符重载方法,可以百度查看,书上列表中,已经列明了至少27类,其他的应该还有

2、索引和分片:__getitem__和__setitem__

我们先来看索引和分片的运算符重载,当实例X出现在X[i]这样的索引运算中时,Python会调用这个实例继承的__getitem__方法,把X作为第一位参数传入,并且将方括号内的索引值传递给第二个参数,具体代码如下:

__getitem__是查看类属性的值,可以通过索引,而__setitem__是更新类属性的值,主要是针对有键值对的,具体代码实例如下:

3、索引迭代:__getitem__

也就是说,如果有该方法存在,那该类的对象,是可迭代的,例如,承接上面的例子,可以通过list()函数直接查看实例X中的内容

在这里是一个概念或者说技巧,后续在使用中可考虑

4、可迭代对象:__iter__和__next__

虽然上面说的__getitem__可用,但是Python中所有的迭代上下文都会先尝试__iter__方法,再尝试__getitem__,也就是说我们应该优先调整__iter__方法

通过__iter__和__next__方法的结合使用,可以实现类实例的迭代,具体代码如下:

以上是创建了一个类,接下来通过实例来使用迭代功能

5、属性访问:__getattr__和__setattr__

__getattr__是访问属性,__setattr__是修改属性

先创建一个简单的类,如果要访问不存在的属性,系统会出现提示信息,具体代码如下:

对于类,如果你直接添加属性和值是可以的,但是可以通过__setattr__来屏蔽,还是承接上面代码的实例,代码调整如下:

对于以上代码,运行结果如下:

6、字符串显示:__repr__和__str__

关于字符串显示,前面章节中有说明,也有用到__repr__来设计打印类的结果,那与__str__有什么区别呢?

__str__:会首先被打印操作和str内置函数尝试(print运行的内部等价形式),它通常应当返回一个用户友好的显示

__repr__:用于所有其他的场景,如果没有定义__str__则打印操作也会使用__repr__,也就是说可以用于任何地方

通过以下代码,会更好的说明这一点:

首先,看下,如果没有定义__str__和__repr__的情况下会是什么情况

你会发现,直接调用实例或者打印实例,都是显示一串代码,它是说明该实例的内存地址

如果先定义__repr__,看下结果:

再定义__str__看下结果:

7、右侧加法和原位置加法:__radd__和__iadd__

常规定义的__add__一般都是右侧加法,也就是相加的对象在实例的右侧,如果是左侧,系统会提示错误,具体代码示例如下:

通过定义__radd__来解决这个问题

如果要实现【+=】这种原位置加法,可以通过__iadd__来定义,具体代码示例如下:

8、调用表达式:__call__

通过定义__call__可以实现实例不同的调用,具体代码如下:

9、比较运算:__lt__、__gt__和其他方法

这个比较容易理解,就是如果实例与其他比较时,如何处理,具体代码说明如下:

10、布尔测试:__bool__和__len__

Python会首先尝试__bool__来获取一个直接的布尔值,如果没有该方法,就退而求其次的尝试__len__来根据对象的长度确定真值,

系统默认实例对象是真的,如果需要我们特殊的处理,可以通过这个定义不一样的结果,

先看系统默认的情况:

定义新的结果:

11、对象析构函数:__del__

我们知道实例创建的时候会调用__init__来创建,如果实例空间被回收时,就会调用__del__,一般来说,系统是自动调用完成的,在此我们可以了解这个如何运作的,析构函数一般不常用,但是很重要

具体代码示例如下:

本文为作者手打原创,如有引用请取得作者同意

说明:本章内容基于《Python学习手册 第五版》内容学习整理

你可能感兴趣的:(python比较运算符重载)