Skr-Eric的Python课堂(二十二)——Python的异常和运算符重载

2024-03-14 03:10

本文主要是介绍Skr-Eric的Python课堂(二十二)——Python的异常和运算符重载,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

异常(高级)

  with 语句

    语法:

      with 表达式1 [as 变量1], 表达式2 [as 变量2], ...:

         语句块

  作用:

    使用于对资源进行访问的场合,确保使用过程中不管是否发生异常都会执行必须的'清理'操作, 并释放资源

      如:文件打开后自动关闭,线程中锁的自动获取和释放等(线程后面会学)

  说明:

    as 子句中的变量用于绑定表达式执行后生成的对象

    with语句并不会改变异常的状态

 

  示例:

# 第一种方式用try-finally保证文件一定能够正常关闭
try:f = open("../../day19/day19.txt")try:for l in f:x = int('aaaa')  # 出现异常print(l)finally:f.close()print("文件已经关闭")
except OSError:print("打开文件失败")

  环境资源管理器

    1. 类内有 __enter__和 __exit__实例方法的类创建的对象被称为环境管理器

    2. 能够用with语句进行管理的对象必须是环境管理器

    3. __enter__方法将在进入with语句时被调用, 由as变量绑定返回的对象

    4. __exit__方法将在离开with语句时被自动调用,且可以通过参数来判断离开with语句时是否有异常发生

 

  示例:

# 此示例示意自定义的对象加入__enter__ 和 __exit__ 方法,让A类的对象能够使用with使用语句
class A:'''此类的对象可以用于with语句进行管理'''def __enter__(self):print("此方法是在with语句内执行的")return self  # self将 被 with 中的as 变量绑定def __exit__(self, exc_type, exc_val, exc_tb):'''exc_type 用来绑定错误类型,当没有异常发生时绑定Noneexc_val 用来绑定错误对象,当没有发生异常时绑定Noneexc_tb 用来绑定TraceBack对象,当没有异常时绑定None'''if exc_type is None:print("您已离开with语句,离开时没有发生任何异常")else:print("您已离开with语句")print("错误类型是:", exc_type)print("错误对象是:", exc_val)print('Traceback:', exc_tb)with A() as a:print("这是with语句内部的输出")int(input("请输入整数: "))print("程序正常结束")

 

运算符重载

  什么是运算符重载

    让自定义的类生成的对象(实例) 能够使用运行算进行操作

  作用:

    让自定义类的实例像内建对象一样进行运算符操作

    让程序简洁易读

    对自定义对象将运算符赋予新的规则

 

  算术运算符的重载:

    方法名                  运算符和表达式   说明

  __add__(self, rhs)        self + rhs    加法

  __sub__(self, rhs)        self - rhs    减法

  __mul__(self, rhs)        self * rhs    乘法

  __truediv__(self, rhs)    self / rhs    除法

  __floordiv__(self, rhs)   self // rhs   地板除

  __mod__(self, rhs)        self % rhs    取模(求余)

  __pow__(self, rhs)        self ** rhs   幂运算

   

   rhs (right hand side)  右手边

 

  说明:

    运算符重载方法及参数已经有固定的含义,不建议改变原的运算符的含义及参数的意义

 

  二元运算符的重载方法格式:

    def __xxx__(self, other):

        语句块

 

反向算术运算符的重载

  当运算符的左侧为内建类型时,右侧为自定义类型进行算术运算符运算时会出现TypeError错误,因无法修改内建类型的代码实现运算符重载,此时需要使用反向算术运算符重载

 

反向算术运算符的重载:

    方法名                  运算符和表达式   说明

  __radd__(self, lhs)        lhs + self    加法

  __rsub__(self, lhs)        lhs - self    减法

  __rmul__(self, lhs)        lhs * self    乘法

  __rtruediv__(self, lhs)    lhs / self    除法

  __rfloordiv__(self, lhs)   lhs // self   地板除

  __rmod__(self, lhs)        lhs % self    取模(求余)

  __rpow__(self, lhs)        lhs ** self   幂运算

 

示例:

# 此示例示意反向算术运算符的重载
class MyList:def __init__(self, iterable=()):self.data = list(iterable)def __repr__(self):return "MyList(%s)" % self.datadef __add__(self, rhs):return MyList(self.data + rhs.data)def __mul__(self, rhs):'''rhs 为int类型, rhs.data 是不存在的'''print("__mul__ 被调用")return MyList(self.data * rhs)def __rmul__(self, lhs):print("__rmul__被调用")return MyList(self.data * lhs)L1 = MyList([1, 2, 3])
L2 = MyList([4, 5, 6])L3 = 3 * L1
print(L3)

 

复合赋值算术运算符的重载

  以复合赋值算术运算符 x += y 为例, 此运算符会优先调用 x.__iadd__(y) 方法,如果没有__iadd__方法时会将复合赋值运算拆解为: x = x + y 然后调用 x = x.__add__(y) 方法,如果再不存在__add__ 方法则会触发TypeError类型的错误异常

 

复合算术运算符的重载:

    方法名                  运算符和表达式   说明

  __iadd__(self, rhs)        self += rhs    加法

  __isub__(self, rhs)        self -= rhs    减法

  __imul__(self, rhs)        self *= rhs    乘法

  __itruediv__(self, rhs)    self /= rhs    除法

  __ifloordiv__(self, rhs)   self //= rhs   地板除

  __imod__(self, rhs)        self %= rhs    取模(求余)

  __ipow__(self, rhs)        self **= rhs   幂运算

 

比较运算符的重载

    方法名                  运算符和表达式   说明

  __lt__(self, rhs)        self <  rhs   小于

  __le__(self, rhs)        self <= rhs   小于等于

  __gt__(self, rhs)        self >  rhs   大于

  __ge__(self, rhs)        self >= rhs   大于等于

  __eq__(self, rhs)        self == rhs   等于

  __ne__(self, rhs)        self != rhs   不等于

 注: 比较运算符通常返回布尔值True 或 False

 

位相关运算符重载

    方法名                  运算符和表达式   说明

  __and__(self, rhs)        self & rhs   位与

  __or__(self, rhs)         self | rhs   位或

  __xor__(self, rhs)        self ^ rhs   位异或

  __lshift__(self, rhs)     self << rhs  左移

  __rshift__(self, rhs)     self >> rhs  右移

 

反向位运算符重载

    方法名                  运算符和表达式   说明

  __rand__(self, lhs)        lhs & self  位与

  __ror__(self, lhs)         lhs | self  位或

  __rxor__(self, lhs)        lhs ^ self  位异或

  __rlshift__(self, lhs)     lhs << self 左移

  __rrshift__(self, lhs)     lhs >> self 右移

 

复合赋值位相关运算符重载

    方法名                  运算符和表达式   说明

  __iand__(self, rhs)        self &= rhs   位与

  __ior__(self, rhs)         self |= rhs   位或

  __ixor__(self, rhs)        self ^= rhs   位异或

  __ilshift__(self, rhs)     self <<= rhs  左移

  __irshift__(self, rhs)     self >>= rhs  右移

 

一元运算符的重载

  方法名                  运算符和表达式   说明

 __neg__(self)            - self        负号

 __pos__(self)            + self        正号

 __invert__(self)         ~ self        取反

 

 语法:

  class 类名:

      def __xxx__(self):

          ....

  

  示例:

# 此示例示意一元运算符的重载
class MyList:def __init__(self, iterable=()):self.data = list(iterable)def __repr__(self):return "MyList(%s)" % self.datadef __neg__(self):G = (-x for x in self.data)return MyList(G)L1 = MyList([1, -2, 3, -4, 5])
L2 = -L1  # <<---此处会有错误
print(L2)  # MyList([-1, 2, -3, 4, -5])

 

in / not in 运算符重载

  格式:

    def __contains__(self, e):

        语句

 

  注: in / not in 返回布尔值 True/False

    当重载了__contains__后, in 和 not in 运算符都可用.

    not in 运算符的返回值与 in 相反

  示例:

# 此示例示意 in / not in 运算符的重载class MyList:def __init__(self, iterable=()):self.data = list(iterable)def __repr__(self):return "MyList(%s)" % self.datadef __contains__(self, e):# print("+++++++++")return True if e in self.data else False# return e in self.dataL1 = MyList([1, -2, 3, -4, 5])if 2 in L1:  # 等同于 if L1.__contains__(2):print("2在L1内")
else:print('2不在L1内')if 4 not in L1:  # 等同于 if not L1.__contains__(4)print("4不在L1内")
else:print("4在L1内")

 

索引和切片运算符重载方法:

  方法名                   运算符和表达式       说明

 __getitem__(self, i)     x = self[i]    索引/切片取值

 __setitem__(self, i, v)  self[i] = v    索引/切片赋值

 __delitem__(self, i)     del self[i]  del语句删除索引/切片

 

作用:

  让自定义的类型的对象能够支持索引和切片操作

 

  示例:

from __future__ import unicode_literals# 此示例示意 in / not in 运算符的重载class MyList:def __init__(self, iterable=()):self.__data = list(iterable)def __repr__(self):return "MyList(%s)" % self.__datadef __getitem__(self, i):'索引取值,i绑定[]内的元素'print('i的值是:', i)return self.__data[i]  # 返回data绑定列表中的第i个元素def __setitem__(self, i, v):'''此方法可以让自定义的列表支持索引赋值操作'''print("__setitem__被调用, i=", i, 'v=', v)self.__data[i] = vdef __delitem__(self, i):self.__data.pop(i)  # del self.__data[i]L1 = MyList([1, -2, 3, -4, 5])
x = L1[3]  # 能否用索引来访问自定义的MyList类型的对象呢
print(x)L1[3] = 400  # 索引赋值
print(L1)del L1[3]
print(L1)  # MyList([1, -2, 3, 5])# 思考如下语句能执行吗?
print(L1[::2])  # 切片取值
# 此示例示意切片取值操作
class MyList:def __init__(self, iterable=()):self.__data = list(iterable)def __repr__(self):return "MyList(%s)" % self.__datadef __getitem__(self, i):print('i的值是:', i)if type(i) is int:print("用户正在用索引取值")elif type(i) is slice:print("用户正在用切片取值")print("切片的起点是:", i.start)print("切片的终点是:", i.stop)print("切片的步长是:", i.step)elif type(i) is str:print("用户正在用字符串进行索引操作")# raise KeyErrorreturn "你想用字符串做什么?"return self.__data[i]  # 返回data绑定列表中的第i个元素L1 = MyList([1, -2, 3, -4, 5])
print(L1[::2])  # 切片取值
print(L1["ABC"])

 

  slice构造函数

    作用:

      用于创建一个slice对象,此对于用于切片操作的传值

    格式:

      slice(start=None, stop=None, step=None)

    slice对象的实例属性:

      start  切片的起始值 默认为None

      stop   切片的终止值 默认为None

      step   切片的步长 默认为None

 

特性属性 @property

  实现其它语言所拥有的getter 和 setter功能

 

  作用:

    用来模拟一个属性

    通过@property装饰器,可以对模拟属性的赋值和取值加以控制

  示例:

from __future__ import unicode_literals
# property.pyclass Student:def __init__(self, s):self.__score = sdef setScore(self, s):'''此方法用设置值加以限制以保证数据的准确性setter是用来数据的'''if 0 <= s <= 100:self.__score = sdef getScore(self):'''getter 只用来获取数据'''return self.__scores = Student(50)
s.setScore(100)# s.score = 100
# print(s.score)
# s.score = 10000
# print(s.score)

 

 

课后习题:

  实现有序集合类OrderSet , 能实现两个集合的交集 &, 并集 |, 补集-, 对称补集 ^, ==,!=,in / not in 等操作

  要求: 集合的内部用list存储数据

s1 = OrderSet([1, 2, 3, 4])
s2 = OrderSet([3, 4, 5])
print(s1 & s2)  # OrderSet([3, 4])
print(s1 | s2)  # OrderSet([1, 2, 3, 4, 5])
print(s1 ^ s2)  # OrderSet([1, 2, 5])
if OrderSet([1, 2, 3]) != OrderSet(1, 2, 3, 4):print("不相等")
else:print("相等")
if s1 == OrderSet([3, 4, 5]):print("s1 == OrderSet([3, 4, 5])")
if 2 in s1:print('2 in s1 返回真')... 以下自己测试

 

 

 

想要看更多的课程请微信关注SkrEric的编程课堂

这篇关于Skr-Eric的Python课堂(二十二)——Python的异常和运算符重载的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/807029

相关文章

Python脚本实现自动删除C盘临时文件夹

《Python脚本实现自动删除C盘临时文件夹》在日常使用电脑的过程中,临时文件夹往往会积累大量的无用数据,占用宝贵的磁盘空间,下面我们就来看看Python如何通过脚本实现自动删除C盘临时文件夹吧... 目录一、准备工作二、python脚本编写三、脚本解析四、运行脚本五、案例演示六、注意事项七、总结在日常使用

Python将大量遥感数据的值缩放指定倍数的方法(推荐)

《Python将大量遥感数据的值缩放指定倍数的方法(推荐)》本文介绍基于Python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处理,并将所得处理后数据保存为新的遥感影像... 本文介绍基于python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处

python管理工具之conda安装部署及使用详解

《python管理工具之conda安装部署及使用详解》这篇文章详细介绍了如何安装和使用conda来管理Python环境,它涵盖了从安装部署、镜像源配置到具体的conda使用方法,包括创建、激活、安装包... 目录pytpshheraerUhon管理工具:conda部署+使用一、安装部署1、 下载2、 安装3

Python进阶之Excel基本操作介绍

《Python进阶之Excel基本操作介绍》在现实中,很多工作都需要与数据打交道,Excel作为常用的数据处理工具,一直备受人们的青睐,本文主要为大家介绍了一些Python中Excel的基本操作,希望... 目录概述写入使用 xlwt使用 XlsxWriter读取修改概述在现实中,很多工作都需要与数据打交

使用Python实现在Word中添加或删除超链接

《使用Python实现在Word中添加或删除超链接》在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能,本文将为大家介绍一下Python如何实现在Word中添加或... 在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能。通过添加超

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

利用Python编写一个简单的聊天机器人

《利用Python编写一个简单的聊天机器人》这篇文章主要为大家详细介绍了如何利用Python编写一个简单的聊天机器人,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 使用 python 编写一个简单的聊天机器人可以从最基础的逻辑开始,然后逐步加入更复杂的功能。这里我们将先实现一个简单的

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一