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)