学习笔记☞python 基础☞属性管理函数 and 异常(with语句) and 运算符重载 ☞python3

属性管理函数

函数说明
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

异常(高级)

    with 语句

        语法:
            with 表达式1 [as 变量名1], 表达式2 [as 变量名2], ...
        作用:
            用于对资源访问的场合,确保使用过程中不管是否发生异常,都会执行必要有'清理'操作,并释放资源
        如:
            文件打开后自动关闭,线程中锁的自动获取和释放(线程后面会讲)
        说明:
            with 语句与 try-finally相似,并不会改变异常状态
            as 子句用于绑定表达式创建的对象
示例:
# 此示例示意with语句的使用方法
# 打开文件读取文件数据
def read_file():
    try:
        f = open('a.txt')
        try:
            while True:
                s = f.readline()
                if not s:
                    return
                int(input('请输入任意数字打印下一行:'))
                print(s.rstrip())
        finally:
            f.close()
            print('文件关闭')
    except IOError:
        print('已转正常')
    except ValueError:
        print('已转正常')


def read_file_with():
    try:
        with open('a.txt') as f:
            while True:
                s = f.readline()
                if not s:
                    break
                int(input('请输入任意数字打印下一行:'))
                print(s.rstrip())
    except IOError:
        print('已转正常')
    except ValueError:
        print('已转正常')


if __name__ == '__main__':
    read_file()
    # 下为with 语句
    read_file_with()
环境管理器:
    1、类内有__enter__和__exit__方法的类被称为环境管理器
    2、能够用with进行管理的对象必须是环境管理器
    3、__enter__ 将在进入with语句时被调用,并返回有as变量管理的对象
    4、__exit__将在离开with语句是被调用,且可以用参数来判断离开with语句时是否出现异常并做出相应的处理

示例:
# 本程序示意自定义的类作为资源管理器使用
class FileWrite:
    def __init__(self, filename):
        self.filename = filename  # 此属性用于记住文件名

    def writeline(self, s):
        '''此方法用于向文件写入字符串,同时自动添加换行'''
        self.file.write(s)
        self.file.write('\n')

    def __enter__(self):
        '''此方法用于实现环境管理器'''
        self.file = open(self.filename, 'w')
        print('已进入__enter__方法,文件打开成功')
        return self  # 返回值用于向with中的as绑定

    def __exit__(self, exc_type, exc_val, exc_tb):
        '''

        :param exc_type: 为异常类型,没有异常发生时为None
        :param exc_val:为错误的对象,没有异常时为None
        :param exc_tb: 为错误的traceback对象
        :return:
        '''
        self.file.close()
        print('文件', self.filename, '已经关闭')
        if exc_type is None:
            print('退出with语句时没有异常')
        else:
            print('退出with语句时有异常,类型是', exc_type, '错误是', exc_val)
        print('__exit__方法被调用,已离开with语句')


if __name__ == '__main__':

    try:
        with FileWrite('log.txt') as fw:
            while True:
                s = input('请输入一行:')
                if s == 'exit':
                    break
                if s == 'error':
                    raise ValueError('故意制造的值错误')
                fw.writeline(s)
    except:
        print('有错误发生')

    print('这是with语句之外,也是程序的最后一条语句')
练习:
'''
实现文件的复制(建议使用二进制方式)
    $ python3 mycp.py
      请输入源文件:/etc/passwd
      请输入目标文件:./mypass.txt
      提示 '文件复制成功' 或 '文件复制失败'
      建议使用with语句打开文件
'''


def cp(src_file, dst_file):
    '''

    :param sou_file: 源文件路径
    :param obj_file: 目标文件路径
    :return: 结果提示
    '''
    try:
        with open(src_file, 'rb') as f_s, open(dst_file, 'wb') as f_d:
            # 如果此文件过大则分次进行搬移
            while True:
                b = f_s.read(4096)
                if not b:  # 如果字节为空停止复制
                    break
                f_d.write(b)
        return '文件复制成功'
    except:
        return '文件复制失败'


def main():
    src = input('请输入源文件:')
    dst = input('请输入目标文件:')
    r = cp(src, dst)
    print(r)


if __name__ == '__main__':
    main()

运算符重载:

    什么是运算符重载:

        让自定义的类生成的对象(实例)能够使用运算符进行操作
    作用:
        让实例象数学表达式一样进行运算操作
        让程序简洁易读
    说明:
        运算符重载方法的参数已经有固定的含义,不建议改变与哪有的含义

算数运算符:

    方法名         运算符
  __add__          加法+
  __sub__          减法-
  __mul__          乘法*
  __truediv__      除法/
  __floordiv__     地板除//
  __mod__          取模%
  __pow__          幂**

二元运算符重载方法格式:
    def __xxx__(self,other):
        ....
示例:
# 此程序示意运算符重载
class MyNumber:
    def __init__(self, v):
        self.data = v

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

    def __add__(self, other):
        print('__add__方法被调用')
        obj = MyNumber(self.data + other.data)
        return obj

    def __sub__(self, other):
        obj = MyNumber(self.data - other.data)
        return obj


n1 = MyNumber(100)
n2 = MyNumber(200)
# n3 = n1.__add__(n2)
n3 = n1 + n2  # 等同于n3 = n1.__add__(n2)o
print('n3 =',n3)
n4 = n2 - n1
print('n4 =',n4)
练习:
    实现两个自定义表的相加
    class MyList:
        def __init__(self,iterable):
            self.data=[x for x in iterable]
    L1=MyList([1,2,3])
    L2=MyList(range(4,7))
    L3=L1+L2
    print('L3 =',L3)#MyList([1,2,3,4,5,6])
    L4=L1*2
    print('L4 =',L4)MyList([1,2,3,1,2,3])

class MyList:

    def __init__(self, iterable):
        self.data = [x for x in iterable]

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

    def __add__(self, other):
        return MyList(self.data + other.data)

    def __mul__(self, other):
        return MyList(self.data * other)


L1 = MyList([1, 2, 3])
L2 = MyList(range(4, 7))
L3 = L1 + L2
print('L3 =', L3)  # MyList([1,2,3,4,5,6])
L4 = L1 * 2
print('L4 =', L4)  # MyList([1, 2, 3, 1, 2, 3])

反向算数运算符:

    方法名         运算符
  __radd__          加法+
  __rsub__          减法-
  __rmul__          乘法*
  __rtruediv__      除法/
  __rfloordiv__     地板除//
  __rmod__          取模%
  __rpow__          幂**

示例:
# 此示例示意反向算数运算符


class MyList:

    def __init__(self, iterable):
        self.data = [x for x in iterable]

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

    def __mul__(self, rhs):
        return MyList(self.data * rhs)

    def __rmul__(self, lhs):
        print('__rmul__被调用,lhs =', lhs)
        return MyList(self.data * lhs)


L1 = MyList([1, 2, 3])
L2 = MyList(range(4, 7))
L4 = L1 * 2
print('L4 =', L4)  # MyList([1, 2, 3, 1, 2, 3])
L5 = 2 * L1
print('L4 =', L5)  # MyList([1, 2, 3, 1, 2, 3])

复合赋值运算符重载

        方法名         运算符
  __iadd__          加法+
  __isub__          减法-
  __imul__          乘法*
  __itruediv__      除法/
  __ifloordiv__     地板除//
  __imod__          取模%
  __ipow__          幂**

示例:
# 此示例示意复合赋值算数运算符


class MyList:

    def __init__(self, iterable):
        self.data = [x for x in iterable]

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

    def __add__(self, other):
        print('__add__被调用')
        return MyList(self.data + other.data)

    def __iadd__(self, other):  # 在+=中优先调用此方法,没有则调用__add__方法
        print('__iadd__方法被调用')
        self.data.extend(other.data)
        return self


L1 = MyList([1, 2, 3])
L2 = MyList(range(4, 7))
print('id(L1)=', id(L1))
L1 += L2  # 相当于L1 = L1 + L2
print('L1 =', L1)
print('id(L1)=', id(L1))
问题:
    # 算法一
    a=[100]
    def test(x):
        x=x+x
        print(x)
    test(a)
    print(a)

    # 算法二
    a=[100]
    def test(x):
        x+=x
        print(x)
    test(a)
    print(a)

比较运算符的重载

    __lt__      对应  < 小于
    __le__      对应  <= 小于等于
    __gt__      对应  > 大于
    __ge__      对应  >= 大于等于
    __eq__      对应  == 等于
    __ne__      对应  != 不等

注:
    比较运算符通常返回True和False

位运算符重载


    __inert__       ~取反(一元运算符)
    __and__         &位与(交集)
    __or__          |位与(并集)
    __xor__         ^位与(差集)
    __lshift__      <<左移
    __rshift__      >>右移

反向位运算符重载


    __rinert__       ~取反(一元运算符)
    __rand__         &位与(交集)
    __ror__          |位与(并集)
    __rxor__         ^位与(差集)
    __rlshift__      <<左移
    __rrshift__      >>右移

复合赋值运算符重载

    __iinert__       ~取反(一元运算符)
    __iand__         &位与(交集)
    __ior__          |位与(并集)
    __ixor__         ^位与(差集)
    __ilshift__      <<左移
    __irshift__      >>右移


一元运算符的重载:

    __neg__         -负号
    __pos__         +正号
    __invert__      ~按位取反
格式:
    def __xxx__(self):
        ....
示例:
# 此示例示意一元运算符重载


class MyList:

    def __init__(self, iterable):
        self.data = [x for x in iterable]

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

    def __neg__(self):
        print('__neg__方法被调用')
        return MyList(-x for x in self.data)  # 生成器表达式


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

in 和 not in 运算符的重载

格式:
    def __contains__(self,e):   # e 代表元素
        ...
说明:
    not in 相当于in取反,所有只需要重载 in 即可
示例:
# 此示例示意in / not in 运算符重载


class MyList:

    def __init__(self, iterable):
        self.data = [x for x in iterable]

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

    def __contains__(self, e):  # e 代表元素
        print('__contains__被调用')
        for x in self.data:
            if x == e:
                return True
        return False


L1 = MyList([1, -2, 3, -4, 5])
if 2 in L1:  # 需要重载__contains__方法
    print('2在L1中')
else:
    print('2不在L1中')

索引和切片运算符的重载:

    重载方法
        __getitem__(self, item)             用于索引/切片取值
        __setitem__(self, key, value)       用于索引/切片赋值
        __delitem__(self, key)              用于del语句删除索引操作

    作用:
        让自定义的类型的对象能够支持索引和切片操作
    示例:
# 此示例示意索引 index 运算符重载


class MyList:

    def __init__(self, iterable):
        self.data = [x for x in iterable]

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

    def __getitem__(self, item):
        print('__getitem__被调用', item)
        return self.data[item]

    def __setitem__(self, key, value):
        self.data[key] = value

    def __delitem__(self, key):
        del self.data[key]


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

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

# 此示例示意切片 slice 运算符重载


class MyList:

    def __init__(self, iterable):
        self.data = [x for x in iterable]

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

    def __getitem__(self, item):
        print('__getitem__被调用', item)
        if type(item) is slice:
            print('正在进行切片操作')
        elif type(item) is int:
            print('正在进行索引操作')
        return self.data[item]

    def __setitem__(self, key, value):
        self.data[key] = value

    def __delitem__(self, key):
        del self.data[key]


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

print(L1[::2])  # ::2等同于slice(None, None, 2)
L1 = MyList([1, -2, 3, -4, 5])
L1[::2] = (2, 4, 6)
print(L1)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值