| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
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相关的代码不照着敲,摸索着敲个几遍,大概就能理解了。 
 
                *:不照着敲的意思就是不对着屏幕和书本代码一个一个的敲,按自己理解回忆着去敲。 |   
 
 
 
 |