Python学习day21

异常(高级)
  异常相关的语句:
    try-except 
    try-finally
    raise 触发异常,发生错误通知
    assert 根据条件触发AssertionError类型的错误通知
    with 语句


with 语句
  语法:
    with 表达式1 [as 变量1],表达式2 [as 变量2], ...:
       语句块 
  作用:
    使用于对资源进行访问的场合,确保使用过程中不管是否发生异常,都会执行必须的'清理'操作,并释放资源
      如: 文件使用后自动关闭,线程中锁的自动获取和释放等
  说明:
    执行表达式 用as 子句中的变量绑定生成的对象
    with 语句并不必变异常的状态
  示例见:
    with.py

环境管理器(也有叫上下文管理器)
  1. 类内有__enter__方法 和 __exit__ 实例方法的类被称为环境管理器
  2. 能够用with语句进行管理的对象必须是环境管理器
  3. __enter__将在进入with语句时被调用,并返回由 as 变量绑定的对象
  4. __exit__ 将在离开with语句时被调用, 且可以用参数来判断在离开with语句时是否有异常发生并做出相应的处理

# with4.py


# 此示例示意环境管理器类的定义的使用
class A:
    '''此类的对象可以用于with语句进行管理'''
    def __enter__(self):
        print("已经进入with语句")
        return self

    def __exit__(self, exc_type, exc_value, exc_tb):
        print("已经离开了with语句")
        if exc_type is None:
            print("在with语句内部没有发生异常,正常离开with")
        else:
            print("离开with语句时出现异常")
            print("异常类型是:", exc_type)
            print("错误的值是:", exc_value)

try:
    with A() as a:
        print("这是with语句里打印的")
        3 / 0  # 触发异常
except:
    print("有异常发生,程序已转为正常!")

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 hands side) 右手边

# mynumber.py

# 此示例示意自定义的类通过运算符重载实现运算符操作
class MyNumber:
    def __init__(self, v):
        self.data = v

    def __repr__(self):
        return "MyNumber(%d)" % self.data

    def __add__(self, other):
        '''实现加法操作,生成一个新的对象并返回给调用者'''
        print("__add__方法被调用")
        return MyNumber(self.data + other.data)
    def __sub__(self, rhs):
        return MyNumber(self.data - rhs.data)

n1 = MyNumber(100)
n2 = MyNumber(200)
n3 = n1 + n2  #  等同于n1.__add__(n2)
# n3 = n1.__add__(n2)

print(n1, "+", n2, '=', n3)  # MyNumber(300) ???
n4 = n1 - n2
print('n4 =', n4)

二元运算符的重载方法格式:
  def __xxx__(self, other):
      运算规则的语句...

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

反向算术运算重载
  方法名                  运算符和表达式    说明 
  __radd__(self, rhs)      lhs +  self     加法
  __rsub__(self, rhs)      lhs -  self     减法
  __rmul__(self, rhs)      lhs *  self     乘法
  __rtruediv__(self, rhs)  lhs /  self     除法
  __rfloordiv__(self, rhs) lhs // self     地板法
  __rmod__(self, rhs)      lhs %  self     求余(取模)
  __rpow__(self, rhs)      lhs ** self     冪运算


复合赋值算术运算符重载
  以复合赋值算术运算符 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

位运算符的重载
  方法名                  运算符和表达式    说明 
  __invert__(self, rhs)    ~self    取反(一元运算符)
  __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, rhs)       lhs &  self     位与
  __ror__(self, rhs)        lhs |  self     位或
  __rxor__(self, rhs)       lhs ^  self     位异或
  __rlshift__(self, rhs)    lhs << self     左移
  __rrshift__(self, rhs)    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       取反

  语法格式:
      def __xxx__(self):
          ...

# 此示例示意一元运算符的重载
class MyList:
    def __init__(self, iterable=()):
        self.data = [x for x in iterable]

    def __repr__(self):
        return 'MyList(%r)' % self.data

    def __neg__(self):
        '''规则是正变负,负变正'''
        # L = [-x for x in self.data]
        L = (-x for x in self.data)
        return MyList(L)

L1 = MyList([1, -2, 3, -4, 5])
L2 = -L1  # 等同于L1.__neg__()
print(L2)

in / not in 运算符
  __contains__(self, e)   e in self   成员运算

# 此示例示意一元运算符的重载
class MyList:
    def __init__(self, iterable=()):
        self.data = [x for x in iterable]

    def __repr__(self):
        return 'MyList(%r)' % self.data

    def __contains__(self, e):
        return e in self.data

L1 = MyList([1, -2, 3, -4, 5])
if 3 in L1:
    print("3 在 L1内")
else:
    print("3 不在 L1内")

if 4 not in L1:
    print('4 不在L1内')
else:
    print('4 在L1内')

索引和切片运算符的重载
  []

  重载方法               运算符和表达式  说明
__getitem__(self, i)    x = self[i]  索引/切片取值
__setitem__(self,i,val) self.[i]=val 索引/切片赋值
__delitem__(self, i)    del self[i]  del语句索引/切片

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


# 此示例示意[]运算符的重载
class MyList:
    def __init__(self, iterable=()):
        self.data = [x for x in iterable]

    def __repr__(self):
        return 'MyList(%r)' % self.data

    def __getitem__(self, i):
        print("i =", i)
        return self.data[i]
    def __setitem__(self, i, val):
        self.data[i] = val

L1 = MyList([1, -2, 3, -4, 5])
x = L1[0]  # L1.__getitem__(0)
print(x)

L1[1] = 2  # L1.__setitem__(1, 2)
print(L1)

slice 构造函数
  作用:
    用于创建一个slice切片对象, 此对象存储一个切片起始值,终止值, 步长值信息
  格式:
    slice(start=None, stop=None, step=None) 创建 一个slice 切片对象
  slice 对象属性
    s.start 切片的起始值
    s.stop 切片的终止值
    s.step 要片的步长

特性属性 @property
  实现其它语言所拥有的 getter 和 setter功能

  作用:
    用来模拟一个属性
    通过@property装饰器可以对模拟的属性赋值和取值加以控制

  示例见:

# property.py

# 此示例示意特性属性的用法
class Student:
    def __init__(self, score):
        self.__score = score

    def get_score(self):
        '''实现getter'''
        return self.__score

    def set_score(self, s):
        '''实现setter'''
        print("正在调用setter")
        if 0 <= s <= 100:
            self.__score = s
        else:
            raise ValueError

    score = property(get_score, set_score)

s = Student(59)
print(s.score)  # print(s.get_score())
s.score = 97  # s.set_score(97)
print(s.score)  # ...

示例2:

# property.py

# 此示例示意特性属性的用法
class Student:
    def __init__(self, score):
        self.__score = score

    @property
    def score(self):  # score = propery(score)
        '''实现getter'''
        return self.__score


    @score.setter
    def score(self, s):
        '''实现setter'''
        print("正在调用setter")
        if 0 <= s <= 100:
            self.__score = s
        else:
            raise ValueError

s = Student(59)
print(s.score)  # print(s.get_score())
s.score = 97  # s.set_score(97)
print(s.score)  # ...

猜你喜欢

转载自blog.csdn.net/sinat_42311311/article/details/81172833
今日推荐