马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 heidern0612 于 2018-12-28 09:42 编辑
写心得的过程都是自我思考的过程,借鉴了论坛很多前辈的回答和方法,如有错误,恳请指出,不胜感激!!!
这一讲课后习题很艰难,想到有点昏头涨脑,老师给的答案如果对指令不太敏感的话,也比较难以理解。
有些指令学的似是而非,还是用的比较少的缘故,所以这一讲之后决定暂时先静下心来,花半个月的时间,努力先打好基础再往后面写。
小插曲之笑尿:打dict的时候,总是不自主的打成dick,卧槽我就这么跟脏话有缘?
PS:如果字比较小,请按下CTRL+鼠标滚轮缩放字体大小,不谢。
0、编写一个程序,统计当前目录下每个文件类型的文件数
佳宇老师思路分析:
1、把指针指定在当前目录,列出所有目录下的文件名;用dict()函数创建一个字典,赋值给type_dict。
2、for循环遍历当前目录所有文件名,判断当前文件是否是文件夹:
是:创建字典默认值,并且字典里唯一的键(key)‘文件夹’的值'0'自增1,此步骤用于统计文件夹数量。
否:用splittext分离文件名和后缀名,把后缀名指定给ext变量,创建字典默认值,ext(后缀名=文件类型)对应键的值自增1,此步骤用于统计文件类型数量。
3、for循环遍历type_dict的键,打印出来键和键所对应的值。
*有的同学可能有点迷糊,key怎么能自增1 ?什么意思不明白。
这里key自增1,自增的是自己的value值,而不是key值。
字典访问key的时候,访问的不是自己的value吗?
import os
all_files = os.listdir(os.curdir) # listdir列出当前目录所有文件名,有点dos基础的同学应该都不迷糊,curdir指定当前目录。
type_dict = dict()
for each_file in all_files:
if os.path.isdir(each_file): # 判断指定路径是否存在且是一个目录
type_dict.setdefault('文件夹', 0) #如果键不存在于字典中,将会添加键并将值设置为默认值
type_dict['文件夹'] += 1
else:
ext = os.path.splitext(each_file)[1] #分离文件名与后缀名 [0]文件名,[1]后缀名
type_dict.setdefault(ext, 0)
type_dict[ext] += 1
for each_type in type_dict.keys():
print('该文件夹下共有类型为【%s】的文件 %d 个' % (each_type, type_dict[each_type]))
1、编写一个程序,计算当前文件夹下所有文件的大小,这两道题思路差不多,我就缩写了。
佳宇老师思路分析:
1、把指针指定在当前目录,列出所有目录下的文件名,赋值给变量all_files;创建一个空字典。
2、for循环遍历当前目录所有文件名,判断当前文件是否是文件:
是:统计文件大小,将其赋值给字典中[each_file]键对应的值。
3、for循环遍历file_dict.items,打印出来键和键所对应的值。
import os
all_files = os.listdir(os.curdir)
file_dict = dict()
for each_file in all_files:
if os.path.isfile(each_file): #判断指定路径是否存在且是一个文件
file_size = os.path.getsize(each_file)
file_dict[each_file] = file_size
for each in file_dict.items():
print('%s【%dBytes】' % (each[0], each[1]))
2、 编写一个程序,用户输入文件名以及开始搜索的路径,搜索该文件是否存在。如遇到文件夹,则进入文件夹继续搜索,程序实现如图:
佳宇老师思路分析:
1、定义一个函数,两个形参,改变当前目录为用户Input输入目录。
2、for循环遍历当前用户输入目录下所有文件名:
A、如果each_file和用户输入文件名相比较,名字相等,打印当前目录+分隔符+当前文件名;
B、如果each_file循环到的是个文件夹的话,调用递归,再次搜索目标文件,返回上一级目录。
*:这里为何要返回上一级的目的一是为了防止文件夹是个空文件夹,没有目标文件,二是为了防止例如三级和四级目录下有相同目标文件的情况。
跳出递归的关键是,递归到each_file是文件的时候,就不会调用递归(当前目录下只有一个文件,没有文件夹)。
这个时候肯定要返回上一级目录,进行下一次文件和文件夹的判断。import os
def search_file(start_dir, target) :
os.chdir(start_dir) # 改变工作目录
for each_file in os.listdir(os.curdir) :
if each_file == target :
print(os.getcwd() + os.sep + each_file) # getcwd返回当前工作目录 sep输出操作系统路径分隔符
if os.path.isdir(each_file) : #判断指定路径是否存在且是一个目录
search_file(each_file, target) # 递归调用
os.chdir(os.pardir) # 递归调用后切记返回上一层目录
start_dir = input('请输入待查找的初始目录:')
target = input('请输入需要查找的目标文件:')
search_file(start_dir, target)
另类实现:import os
def getRoutes(dest_dir, dest_file):
for root, dirs, files in os.walk(dest_dir):
for file in files:
if file == dest_file:
print('%s\%s' % (root, file))
dest_dir = input('请输入待查找的初始目录:')
dest_file = input('请输入待查找的目标文件:')
getRoutes(dest_dir, dest_file)
3、编写一个程序,用户输入开始搜索的路径,查找该路径下(包含子文件夹内)所有的视频格式文件(要求查找mp4 rmvb, avi的格式即可),并把创建一个文件(vedioList.txt)存放所有找到的文件的路径,程序实现如图:
如果上面三道题认真看老师思路的同学,这道题应该比较好理解,就不多说了。
import os
def search_file(start_dir, target) :
os.chdir(start_dir)
for each_file in os.listdir(os.curdir) :
ext = os.path.splitext(each_file)[1]
if ext in target :
vedio_list.append(os.getcwd() + os.sep + each_file + os.linesep) # 使用os.sep是程序更标准
if os.path.isdir(each_file) :
search_file(each_file, target) # 递归调用
os.chdir(os.pardir) # 递归调用后切记返回上一层目录
start_dir = input('请输入待查找的初始目录:')
program_dir = os.getcwd()
target = ['.mp4', '.avi', '.rmvb']
vedio_list = []
search_file(start_dir, target)
f = open(program_dir + os.sep + 'vedioList.txt', 'w')
f.writelines(vedio_list)
f.close()
另类实现:import os
def saveRoutes():
dest_dir = input('请输入待查找的初始目录:')
dest_suffix = input('请输入目标文件后缀:')
f = open('output.txt', 'w')
for root, dirs, files in os.walk(dest_dir):
for file in files:
suffix = os.path.splitext(file)[1]
if suffix == dest_suffix:
f.write('%s\%s
' % (root, file))
f.close()
4、编写一个程序,用户输入关键字,查找当前文件夹内(如果当前文件夹内包含文件夹,则进入文件夹继续搜索)所有含有该关键字的文本文件(.txt后缀),要求显示该文件所在的位置以及关键字在文件中的具体位置(第几行第几个字符),程序实现如图:
想了一下午,想的头疼。
这一题比较晦涩难明,所以我解释详细一点,看第一个函数的时候一头雾水,有木有?
什么JB玩意一大串的看不明白,环顾这道题,其实这道题是要倒着来看的,从代码末尾的主函数开始理解,细化到开始的打印分支函数。
首先请先理解下这两个函数的概念: A、猛击前往os.walk( )方法概念 B、猛击前往find( )方法概念
OS.walk如果还不知道返回的什么是三元组,偷偷告诉你,返回的就是:0、当前的路径 ; 2、当前的文件夹 ; 3、当前的文件;
老师课堂上根本木有讲有木有?确定大致理解了什么意思,再往下看。
佳宇老师思路(从大到小依次细化:主模块--->分模块--->小模块):
1、调用主函数search_files(主模块),从当前目录中查找可打开的txt文件,并询问是否需要print详细;
需要的话调用print_pos函数(额外分支模块)。
2、调用函数search_in_file(主模块下的分模块),从当前文件查找关键字,如果关键字在某一行中,调用pos_in_line函数(分模块下的小模块)。
3、调用函数pos_in_line函数查找关键字所在的位置,依次上返。
其实说白了这道题更像是嵌套的结构,主模块嵌套(调用)分模块,分模块(调用)嵌套小模块。
主函数在处理的过程中遇到问题调用分支函数,分支函数在处理的过程中遇到问题调用更细的分支函数。
代码分析如下:
import os
#================打印结果==================
#此函数主用于search_files函数需要打印具体位置时,调用此函数将字典类型排序,打印对应行数及位置。
def print_pos(key_dict):
keys = key_dict.keys() #分离字典的key
keys = sorted(keys) # 由于字典是无序的,我们这里对行数进行排序
for each_key in keys:
print('关键字出现在第 %s 行,第 %s 个位置。' % (each_key, str(key_dict[each_key])))
#================在某行查找关键字==================
#此函数主用于定位关键字所在行的位置,返给serch_in_file写入字典value.
def pos_in_line(line, key):
pos = []
begin = line.find(key) #查找关键字在每一行中的位置,赋值给begin
while begin != -1: #不为-1时代表找到了,建议了解下find函数。
pos.append(begin + 1) # 用户的角度是从1开始数
begin = line.find(key, begin+1) # 从下一个位置继续查找
return pos
#================在文件中查找==================
#此函数主用于将文件以行数为索引的key,关键字在行的位置作为value作为字典类型,调用pos_in_line函数处理,将字典返回给search_files函数。
def search_in_file(file_name, key):
f = open(file_name) #打开文本文件
count = 0 # 记录行数
key_dict = dict() # 定义字典,用户存放key所在具体行数对应具体位置
for each_line in f: #遍历文本文件中的每一行
count += 1 #行数记录
if key in each_line: #如果关键字在某一行中
pos = pos_in_line(each_line, key) # key在每行对应的位置 调用pos_in_line函数 传入这个行和关键字
key_dict[count] = pos
f.close()
return key_dict
#================主程序(在目录中查找)==================
#此函数主用于遍历当前目录下可以打开的txt文档,然后调用search_in_file函数进行处理。
def search_files(key, detail): #第一步调用search_file函数 把 key, detail 参数传入进去
all_files = os.walk(os.getcwd()) #遍历当前目录下的所有文档,返回一个三目元祖(1.目录,2.包含路径,3.包含文件),将返回的结果赋值给all_files
txt_files = [] #定义列表txt_files
for i in all_files: #遍历all_files 注意这里的i为单次遍历的三元组,也就是说,这里的i是包含目录、路径和文件的三元组。
for each_file in i[2]: #遍历三元组的第三个值,即遍历文件,这里的each_file为单次遍历的文件
if os.path.splitext(each_file)[1] == '.txt': # 根据后缀判断是否文本文件
each_file = os.path.join(i[0], each_file) #如果each_file 是文本文件 则将该文件的路径名称以及文件名称合并,并赋值给each_file
txt_files.append(each_file) #列表txt_files 中追加each_file 此时的each_file为全路径含文件名 列表中追加的文本文件全路径
for each_txt_file in txt_files: #在列表txt_file中 遍历所有的文本文件 each_txt_file为单次遍历的文本文件名
key_dict = search_in_file(each_txt_file, key) #调用seach_in_file函数,传入单次遍历的文本文件名each_txt_file和用户输入的关键字key
if key_dict:
print('================================================================')
print('在文件【%s】中找到关键字【%s】' % (each_txt_file, key))
if detail in ['YES', 'Yes', 'yes']:
print_pos(key_dict)
key = input('请将该脚本放于待查找的文件夹内,请输入关键字:') #接受用户输入的关键字 key为用户输入的结果
detail = input('请问是否需要打印关键字【%s】在文件中的具体位置(YES/NO):' % key) #请示用户是否打印 detail为请示结果
search_files(key, detail) #调用函数search_files 传入关键字 key, detail
剩下难以理解的就是各个函数、方法灵活的运用了。
如果我写成这样有的同学还不理解,自己把之前几课关于os相关的代码不照着敲,摸索着敲个几遍,大概就能理解了。
*:不照着敲的意思就是不对着屏幕和书本代码一个一个的敲,按自己理解回忆着去敲。 |