Python第四天-文件操作,迭代器,生成器,装饰器

文本文件复制

with open("test.txt", "r", encoding="utf-8") as rf, 
        open("test_copy.txt", "w", encoding="utf-8") as wf:
    arr_len = 1000
    while True:
        val = rf.readline(arr_len)
        if len(val) == 0:
            break
        wf.write(val)

文件操作模式主要有:

  • r 读
  • w 写
  • a 写追加
  • b 二进制

with关键字类似java的try-with-resource语法,会自动帮我们close。

二进制文件复制

with open("1.jpg", "rb") as rf, 
        open("1_copy.jpg", "wb") as wf:
    arr_len = 1000
    while True:
        val = rf.read(arr_len)
        if len(val) == 0:
            break
        wf.write(val)

二进制文件不需要指定编码

迭代器

class my_filter():
    def __init__(self, func, iterable):
        self.func = func
        self.iterable = iterable
        self.iter = iter(self.iterable)

    def __iter__(self):
        return self

    def __next__(self):
        while True:
            item = next(self.iter)
            if self.func(item):
                return item
            else:
                continue


print(list(my_filter(lambda x: x & 1 == 0, [1, 2, 3, 4, 5, 6])))
it = iter(my_filter(lambda x: x & 1 == 0, [1, 2, 3, 4, 5, 6]))
print(next(it))

定义一个类似filter功能的class,my_filter既是可迭代对象,又是迭代器,可迭代对象必须包含__iter__()函数,会创建一个迭代器对象,迭代器必须包含__next__()函数,返回可迭代对象的下一个元素,类似java中的Iterable接口的iterator方法,和Iterator接口的next()方法。
iter()函数会调用可迭代对象的__iter__()函数,next()会调用迭代器的__next__()函数。str,list,set,range,dict等都是可迭代类型。

my_filter_obj = my_filter(lambda x: x & 1 == 0, [1, 2, 3, 4, 5, 6])
it = iter(my_filter_obj)
for i in it:
    print(i)
my_filter_obj = my_filter(lambda x: x & 1 == 0, [1, 2, 3, 4, 5, 6])
for i in my_filter_obj:
    print(i)

for循环既可以循环可迭代对象(默认调用对象的__iter__()函数),也可以循环迭代器对象。当__next__()函数没有元素返回时,会抛出StopIteration异常,for循环也会帮我们捕捉该异常,并结束迭代。

三元表达式

age = 9
age = 0 if age < 0 else age
print(age)

类似其他语言的true?a:b表达式

列表生成器

name_list = ["lisi{}".format(i) for i in range(5)]
print(name_list)

生成器表达式

name_list = ("lisi{}".format(i) for i in range(5))
print(name_list, type(name_list))
for name in name_list:
    print(name)

name_list为generator类型,本质上也是迭代器。

生成器函数

# 自增
def counter():
    index = 0
    while True:
        index += 1
        yield index


incr = counter()
for _ in range(10):
    print(next(incr))

使用yield定义生成器函数,生成器函数执行结果就是一个生成器,每次遇到yield就返回,下一次迭代从yield之后开始执行。生成器的好处是延迟计算,占用内存少。

装饰器

# 装饰器函数
def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        ret = func(*args, **kwargs)
        end_time = time.time()
        print("function invoke spend time: {}".format(end_time - start_time))
        return ret

    return wrapper

# 原函数
def my_sum(iterables):
    return sum(iterables)


my_sum = timer(my_sum)
print(my_sum([1, 2, 3, 4]))

对原函数添加统计执行时间的功能

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        ret = func(*args, **kwargs)
        end_time = time.time()
        print("function invoke spend time: {}".format(end_time - start_time))
        return ret

    return wrapper


@timer # my_sum = timer(my_sum)
def my_sum(iterables):
    return sum(iterables)


print(my_sum([1, 2, 3, 4]))

python提供了一种语法糖,@timer,省去了my_sum = timer(my_sum)语句

def timer(type="file"):
    def time_func(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            ret = func(*args, **kwargs)
            end_time = time.time()
            print("function invoke spend time: {}".format(end_time - start_time))
            print("timer type: {}".format(type))
            return ret

        return wrapper

    return time_func


@timer(type="db")  # my_sum = timer(type="db")(my_sum)
def my_sum(iterables):
    return sum(iterables)

print(my_sum([1, 2, 3, 4]))

装饰器也是可以加参数的,@timer(type="db") 相当于 my_sum = timer(type="db")(my_sum)

原文地址:https://www.cnblogs.com/strongmore/p/13550084.html