zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    MySQL · 引擎特性 · InnoDB 事务锁简介
    锁大全与 GDB调试
    docker(4):coreos+docker+rancher真厉害
    TIDB ---NEW SQL
    Linux的内存回收和交换
    TLS握手优化详解
    北风网JAVA 大数据培训
    MySQL 5.7 深度解析: JSON数据类型使用
    MySQL 5.7 深度解析: 临时表空间
    在Linux最大打开文件数限制下 MySQL 对参数的调整
  • 原文地址:https://www.cnblogs.com/strongmore/p/13550084.html
Copyright © 2011-2022 走看看