Python高级编程(11):上下文管理器和切片

一、with 上下文管理器

1. 文件操作中使用 with 的原因

  1. 使用 open 函数,打开 文件 对文件进行读写之后,一定要使用 close 关闭文件,否则会造成系统资源的浪费
  2. 然而,我们在打开文件,或者是在操作文件的过程中,程序出现了异常,那么此时,我们就无法关闭文件
  3. 所以,使用 with as 语句操作上下文管理器,无论期间是否抛出异常,都能保证 with as 语句执行完毕后自动关闭已经打开的文件
with open("xxx.txt", mode='rb') as file_object:  # file_object所指向的不是open("xxx.txt", mode='rb')这个对象,而是指向这个对象中enter方法的返回值
    data = file_object.read()
    print(data)

# with实现对多个文件的上下文管理
with open("xxx.txt", mode='rb') as f1, open("xxx.txt", mode='rb') as f2:
    data1 = f1.read()
    data2 = f2.read()
    print(data1)
    print(data2)

2. with 实现计时器

统计程序执行的时间,可以实现代码复用

import time


# 计时器类
class Timer:
    def __init__(self):
        self.elapesd = 0  # 定义一个记录总共耗时的实例属性

    def __enter__(self):  # with 语句开始时,调用对象最先执行的一个方法
        self.start = time.time()  # 记录开始时间的定时器
        return self  # timer 指向的是这个返回值,必须存在

    def __exit__(self, exc_type, exc_val, exc_tb):  # with 语句内容执行结束后,再次调用对象中的另一个方法
        self.stop = time.time()  # 记录结束时间的定时器

        self.elapsed = self.stop - self.start  # 记录程序执行时长
        
        return False

# 上下文管理器记录耗时时长
with Timer() as timer:  # timer 指向的是Timer对象中enter方法的返回值(由于返回的结果是self,所以导致timer指向的也是Timer()这个对象
    # 实现10000个数求平方后添加到列表中
    num = []
    for i in range(10000):
        num.append(i ** 2)

print(timer.elapsed)

3. 上下文管理器使用场景

  • 打开文件 - 关闭文件
  • 加锁 - 释放锁
  • 启动定时器 - 停止定时器
  • 改变 - 重置

二、切片

1. 切片定义

取出序列型对象(如liststringtuple)中一个范围对应的元素

2. 切片的语法

对象[起始索引: 终止索引: 步长]

  • 遵循左闭右开原则
  • 步长不写:默认为1
  • 开始索引不写:默认为0
  • 终止索引不写:默认为最长索引
元素 0 1 2 3 4 5 6 7 8 9
正向切片索引 0 1 2 3 4 5 6 7 8 9
反向切片索引 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1

3. 简单切片

3.1 a[start:stop]

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 取出正向索引是5~正向索引是9(不包括9)之间的数
print(a[5:9])  # [5, 6, 7, 8]

# 取出正向索引是5~反向索引是-1(不包括-1)之间的数
print(a[5:-1])  # [5, 6, 7, 8]

# 取出反向索引是-5~正向索引是9(不包括9)之间的数
print(a[-5:9])  # [5, 6, 7, 8]

3.2 切片索引超出范围

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 反向索引超出范围
print(a[-100:5])  # [0, 1, 2, 3, 4]

# 正向索引超出范围
print(a[5:100])  # [5, 6, 7, 8, 9]
print(a[100:1000])  # []

# 正向和反向索引都超出范围
print(a[-100:100])  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# start的位置比stop还靠后,返回的是[]
print(a[6:5])  # []

3.3 切片索引缺省

start的缺省值是 无穷小(​)stop的缺省值是 无穷大(​)

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# start索引缺省
print(a[:5])  # [0, 1, 2, 3, 4]

# stop索引缺省
print(a[5:])  # [5, 6, 7, 8, 9]

# start和stop索引都缺省
print(a[:])  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

4. 切片步长

start对应的位置出发,以step为步长索引序列,未越过stop对应的位置,不包括stop本身。

4.1 步长为正数

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 取出正向索引是0~6之间的数(不包括6),步长是2
print(a[0:6:2])  # [0, 2, 4]

# 取出正向索引是0~7之间的数(不包括7),步长是2
print(a[0:7:2])  # [0, 2, 4, 6]

# 取出负无穷~反向索引是-2(不包括-2),步长是2
print(a[:-2:2])  # [0, 2, 4, 6]

# 取出正向索引是4~正无穷,步长是2
print(a[4::2])  # [4, 6, 8]

4.2 步长为负数

start出发,以步长|step|(绝对值),逆序索引序列,在索引缺省的情况下,start的缺省值是 无穷大(​)stop的缺省值是 无穷小(​)

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# stop缺省,取无穷小(无穷小~5)
print(a[5::-1])  # [5, 4, 3, 2, 1, 0]

# start缺省取无穷大(4~无穷大,不包括4)
print(a[:4:-2])  # [9, 7, 5]

# 列表反转
print(a[::-1])  # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
# 字符串反转
b = "abcdef"
print(b[::-1])  # fedcba

你可能感兴趣的:(python,开发语言)