甜萝 发表于 2022-8-25 14:35

某网站练习题的分析以及解答

本帖最后由 paypojie 于 2022-8-25 15:25 编辑

                        题目编写一个程序,能在当前目录以及当前目录的所有子目录下查找文件名包含指定字符串的文件,并打印出相对路径

                         题目来源链接 https://www.liaoxuefeng.com/wiki/1016959663602400/1017623135437088



正如标题那样 要求: 编写程序 在目录下完成一些操作(查找符合条件的文件)

由于对os模块下的函数理解不深 所以无法自行编写 看了评论区下的一些答案 试着分析
import os

def find(str, path):

    if os.path.isfile(path):

      if str in os.path.split(path):

            print(os.path.abspath(path))

            return

    else:

      for f in os.listdir(path):

            find(str, os.path.join(path, f))

find("readme", '.')
分析如下
根据题目 要查找目录下特定的文件 所以 首先导入os模块 因为据我所知 os和os.path模块有对目录和文件进行操作的函数
import os
然后定义一个函数 函数第一个形参为指定字符串 第二个参数为路径
def find(str,path):
然后就是if条件判断 用os.path.isfile()函数判断传进来的路径对象是否为文件
if os.path.isfile(path):
是文件就进入接下来的if条件判断 如果字符串存在于os.path.split(path) 也就是说 字符串存在 os.apth.split方法返回来的元组中的第二个元素上 条件就为真 然后打印os.path.abspath(path) | 绝对路径 | 然后用return返回
if str in os.path.split(path):
    print(os.path.abspath(path))
    return
接下来 就是else下的语句
用for循环遍历当前目录下的所有子目录以及文件 翻译过来就是 for循环迭代 os.listdir(path)返回的列表 列表里面的值包含了指定路径下所有的文件和文件夹
for f in os.listdir(path):
每次循环 就会调用循环里面的语句 find(str,os.path.join(path,f)) 解释一下 这个函数 就是开头定义的函数 指定的字符串 str没变 路径path发生改变 路径为连接之后的新路径 .和当前目录下的子目录或者文件名连接
find(str,os.path.join(path,f))
完整代码
import os
# c = 0
def find(str,path):
    if os.path.isfile(path):
      if str in os.path.split(path):
            print(os.path.abspath(path))
            return
      # global c
      # if c == 0:
      #   print(c)
      #   c += 1
    else:
      # if c == 0:
      #   c += 1
      #   print(c)
      for f in os.listdir(path):
            find(str,os.path.join(path,f))

find("readme", '.')

里面注释代码表示判断调用函数第一次进入的是if分支语句 还是else分支语句 经过测试 第一次进入的是 else下的语句

如果第一次进入if分支语句 那么就会打印0 否则 进入else分支语句 并打印1

有些许疑惑 实际测试的时候 调用函数 第一次肯定不会进入if 因为传入函数的路径参数 是一个. 这就很奇怪了 难道.表示python文件所在的当前目录 百度了一下

在python中,当前目录、父目录、根目录、子目录的表示
“当前目录:os.listdir(“.”) f1 = open(‘xugang.txt’,’w’)”更多 >

确实是

还有一个疑惑 就是C:\Users\Administrator 是我python文件所在的目录 目录里面的第一级子目录和文件 并没有包含 find("readme", '.')函数中的参数 "readme" 为什么调用时却打印出了那么多符合条件的文件 想了半天 原来是for循环下的函数调用起了关键作用



因为在函数内部调用自身 函数自己调用自己 所以 出现了递归 函数中不使用return关键字也可以正常执行 不知道我的理解是不是对的 如下
调用函数 for循环迭代当前目录的第一个子目录 if条件为false 随即 第一次进入else语句 else语句又调用函数 路径发生改变 函数执行for循环 一直这样执行 直到找到所有符合条件的文件 才会结束这个函数

我之前无法理解 为什么会遍历 C:\Users\Administrator 下的所有子目录和文件 不仅遍历一级子目录和文件 还遍历二级 三级目录和文件以及更多次级的目录和文件 直到遍历完最后级别的目录或者文件

递归是如何做到遍历所有文件和所有级别的目录 还有 好像只能检测出最后级别目录中的符合条件的文件 第一级目录中有符合条件的文件 readme.txt但是没有输出 可能这个程序本身有问题
不知道那位大神能够通俗易懂的讲解讲解 总感觉还是一知半解
期待各位大神精彩评论


netcsk 发表于 2022-8-25 14:52

linux下面直接运行find 命令不香

外酥内嫩 发表于 2022-8-25 14:55

有点灵感了,感觉可以用这个改一下做个批量修改文件名的脚本

甜萝 发表于 2022-8-25 14:55

netcsk 发表于 2022-8-25 14:52
linux下面直接运行find 命令不香
没有配置linux环境 虚拟机中也没有安装linux系列的操作系统

甜萝 发表于 2022-8-25 14:57

外酥内嫩 发表于 2022-8-25 14:55
有点灵感了,感觉可以用这个改一下做个批量修改文件名的脚本
哈哈 我有点想实现你的想法{:300_950:}

rinima 发表于 2022-8-25 15:35

感谢楼主分享

zxc9989 发表于 2022-8-25 15:45

如果禁止使用递归,该如何实现

甜萝 发表于 2022-8-25 17:58

zxc9989 发表于 2022-8-25 15:45
如果禁止使用递归,该如何实现

暂时想不出
页: [1]
查看完整版本: 某网站练习题的分析以及解答