基础 day20

day20笔记

函数

说明

getattr(obj, name[, default])

从一个对象得到对象的属性;getattr(x, 'y') 等同于x.y; 当属性不存在时,如果给

default参数,则返回default,如果没有给出default 则产生一个AttributeError错误

hasattr(obj, name)

用给定的name返回对象obj是否有此属性,此种做法可以避免在getattr(obj, name)时引发错误

setattr(obj, name, value)

给对象obj的名为name的属性设置相应的值value, set(x, 'y', v) 等同于 x.y = v

delattr(obj, name)

删除对象obj中的name属性, delattr(x, 'y') 等同于 del x.y

对象属性管理函数:

 

 

异常(高级)

  异常相关的语句:

    try-except

    try-finally

    raise 触发异常,发生错误通知

    assert 根据条件触发AssertionError类型的错误通知

    with 语句

 

 

with 语句

  语法:

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

       语句块

  作用:

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

      : 文件使用后自动关闭,线程中锁的自动获取和释放等

  说明:

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

    with 语句并不必变异常的状态

  示例见:

  with.py

  

# 此示例示意with语句的用法

 

src_file = input("请输入源文件: ")

 

try:

    src = open(src_file, 'rb')

    try:

        try:

            # 准备打开别一个文件

            dst_file = input("请输入目标文件: ")

            dst = open(dst_file, 'wb')

            try:

                # 开始读写文件

                b = src.read()

                dst.write(b)

            finally:

                # 关闭文件

                dst.close()

        except OSError:

            print('打开写文件失败')

    finally:

        src.close()

except OSError:

    print("打开文件", src_file, '失败')

  

环境管理器(也有叫上下文管理器)

  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):

      运算规则的语句...

 

练习:

  修改昨天的课后练习 MyList 实现两个自定义的列表相加

  class MyList:

      .....

 

  L1 = MyList([1, 2, 3])

  L2 = MyList([4, 5, 6])

  L3 = L1 + L2

  print(L3)  # MyList([1, 2, 3, 4, 5, 6])

  L4 = L2 + L1

  print(L4)  # MyList([4, 5, 6, 1, 2, 3])

 

  思考,能否实现MyList类型的对象与整数相乘?

  L5 = L1 * 2

  print(L5)  # ???

 

 

 

反向算术运算符的重载

  当运算符的左侧为内建类型时,右侧为自定义类型进行算术运算时,会出现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):

          ...

 

  示例见:

    mylist5.py

# 此示例示意一元运算符的重载

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   成员运算

 

示例见:

  mylist6.py

# 此示例示意一元运算符的重载

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语句索引/切片

 

作用:

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

示例见:

  mylist7.py

# 此示例示意[]运算符的重载

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 要片的步长

示例见:

  mylist8.py  # 切片取值

# 此示例示意[]运算符的重载

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)

        if type(i) is slice:

            print("您正在执行切片取值操作")

            print("起始值是:", i.start)

            print("终止值是:", i.stop)

            print("步长是:", i.step)

        return self.data[i]

 

L1 = MyList([1, -2, 3, -4, 5])

x = L1[1:8:2]

print(x)  #

 

 

 

 

 

特性属性 @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)  # ...

      property2.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)  # ...


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值