文本文件复制

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)


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

Python第三天-函数