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创建一个功能完整的Windows风格计算器程序

《使用Python创建一个功能完整的Windows风格计算器程序》:本文主要介绍如何使用Python和Tkinter创建一个功能完整的Windows风格计算器程序,包括基本运算、高级科学计算(如三... 目录python实现Windows系统计算器程序(含高级功能)1. 使用Tkinter实现基础计算器2.

Python开发文字版随机事件游戏的项目实例

《Python开发文字版随机事件游戏的项目实例》随机事件游戏是一种通过生成不可预测的事件来增强游戏体验的类型,在这篇博文中,我们将使用Python开发一款文字版随机事件游戏,通过这个项目,读者不仅能够... 目录项目概述2.1 游戏概念2.2 游戏特色2.3 目标玩家群体技术选择与环境准备3.1 开发环境3

Python中模块graphviz使用入门

《Python中模块graphviz使用入门》graphviz是一个用于创建和操作图形的Python库,本文主要介绍了Python中模块graphviz使用入门,具有一定的参考价值,感兴趣的可以了解一... 目录1.安装2. 基本用法2.1 输出图像格式2.2 图像style设置2.3 属性2.4 子图和聚

Python使用Matplotlib绘制3D曲面图详解

《Python使用Matplotlib绘制3D曲面图详解》:本文主要介绍Python使用Matplotlib绘制3D曲面图,在Python中,使用Matplotlib库绘制3D曲面图可以通过mpl... 目录准备工作绘制简单的 3D 曲面图绘制 3D 曲面图添加线框和透明度控制图形视角Matplotlib

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

基于Python打造一个智能单词管理神器

《基于Python打造一个智能单词管理神器》这篇文章主要为大家详细介绍了如何使用Python打造一个智能单词管理神器,从查询到导出的一站式解决,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 项目概述:为什么需要这个工具2. 环境搭建与快速入门2.1 环境要求2.2 首次运行配置3. 核心功能使用指

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

利用Python打造一个Excel记账模板

《利用Python打造一个Excel记账模板》这篇文章主要为大家详细介绍了如何使用Python打造一个超实用的Excel记账模板,可以帮助大家高效管理财务,迈向财富自由之路,感兴趣的小伙伴快跟随小编一... 目录设置预算百分比超支标红预警记账模板功能介绍基础记账预算管理可视化分析摸鱼时间理财法碎片时间利用财