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提取视频文件中的音频

《详解如何使用Python提取视频文件中的音频》在多媒体处理中,有时我们需要从视频文件中提取音频,本文为大家整理了几种使用Python编程语言提取视频文件中的音频的方法,大家可以根据需要进行选择... 目录引言代码部分方法扩展引言在多媒体处理中,有时我们需要从视频文件中提取音频,以便进一步处理或分析。本文

python多种数据类型输出为Excel文件

《python多种数据类型输出为Excel文件》本文主要介绍了将Python中的列表、元组、字典和集合等数据类型输出到Excel文件中,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一.列表List二.字典dict三.集合set四.元组tuplepython中的列表、元组、字典

VSCode配置Anaconda Python环境的实现

《VSCode配置AnacondaPython环境的实现》VisualStudioCode中可以使用Anaconda环境进行Python开发,本文主要介绍了VSCode配置AnacondaPytho... 目录前言一、安装 Visual Studio Code 和 Anaconda二、创建或激活 conda

pytorch+torchvision+python版本对应及环境安装

《pytorch+torchvision+python版本对应及环境安装》本文主要介绍了pytorch+torchvision+python版本对应及环境安装,安装过程中需要注意Numpy版本的降级,... 目录一、版本对应二、安装命令(pip)1. 版本2. 安装全过程3. 命令相关解释参考文章一、版本对

Java逻辑运算符之&&、|| 与&、 |的区别及应用

《Java逻辑运算符之&&、||与&、|的区别及应用》:本文主要介绍Java逻辑运算符之&&、||与&、|的区别及应用的相关资料,分别是&&、||与&、|,并探讨了它们在不同应用场景中... 目录前言一、基本概念与运算符介绍二、短路与与非短路与:&& 与 & 的区别1. &&:短路与(AND)2. &:非短

讯飞webapi语音识别接口调用示例代码(python)

《讯飞webapi语音识别接口调用示例代码(python)》:本文主要介绍如何使用Python3调用讯飞WebAPI语音识别接口,重点解决了在处理语音识别结果时判断是否为最后一帧的问题,通过运行代... 目录前言一、环境二、引入库三、代码实例四、运行结果五、总结前言基于python3 讯飞webAPI语音

基于Python开发PDF转PNG的可视化工具

《基于Python开发PDF转PNG的可视化工具》在数字文档处理领域,PDF到图像格式的转换是常见需求,本文介绍如何利用Python的PyMuPDF库和Tkinter框架开发一个带图形界面的PDF转P... 目录一、引言二、功能特性三、技术架构1. 技术栈组成2. 系统架构javascript设计3.效果图

Python如何在Word中生成多种不同类型的图表

《Python如何在Word中生成多种不同类型的图表》Word文档中插入图表不仅能直观呈现数据,还能提升文档的可读性和专业性,本文将介绍如何使用Python在Word文档中创建和自定义各种图表,需要的... 目录在Word中创建柱形图在Word中创建条形图在Word中创建折线图在Word中创建饼图在Word

Java捕获ThreadPoolExecutor内部线程异常的四种方法

《Java捕获ThreadPoolExecutor内部线程异常的四种方法》这篇文章主要为大家详细介绍了Java捕获ThreadPoolExecutor内部线程异常的四种方法,文中的示例代码讲解详细,感... 目录方案 1方案 2方案 3方案 4结论方案 1使用 execute + try-catch 记录

Python Excel实现自动添加编号

《PythonExcel实现自动添加编号》这篇文章主要为大家详细介绍了如何使用Python在Excel中实现自动添加编号效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、背景介绍2、库的安装3、核心代码4、完整代码1、背景介绍简单的说,就是在Excel中有一列h=会有重复