鱼C论坛

 找回密码
 立即注册
查看: 77|回复: 1

关于第55讲永久存储(下)动动手第1题

[复制链接]
发表于 昨天 18:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
为方便说明,先把小鱼老师的源代码贴出:
from pathlib import Path
   
def get_files(p, files):
    for each in p.iterdir():
        if str(each) == __file__:
            continue
        if each.is_file() and each.suffix == '.py':
            files.append(each)
        if each.is_dir():
            p = each
            get_files(p, files) # 此处使用递归搜索会更方便
   
    return files

   
   
def count_lines(files):
    lines = 0
    for each in files:
        with open(each, "r", errors="ignore") as f:
            t = f.readlines()
            lines += len(t) - t.count('\n') # 空行不能算,所以要减去空行数量
   
    return lines
   
   
p = Path.cwd()
files = []
   
files = get_files(p, files)
for each in files:
    print(each)

#print(f"一个有 {count_lines(files)} 行代码~")


红色部分是我们的关注点。下面两行红色代码是我测试加的代码,下面有两个问题:
1、经测试,函数get_files(p, files)返回的files列表中仍然包含本程序文件,这是怎么回事?
2、使用files.remove(__file__)为何不能从files中删除本程序?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 18:53 | 显示全部楼层
关于您在第55讲动动手第1题中遇到的问题,我来逐一解释并提供解决方案。

首先,问题核心在于路径比较和类型匹配。以下是详细分析:

问题1:为什么 get_files 函数返回的列表中包含本程序文件?
原因在于代码中使用 str(each) == __file__ 进行比较时,路径的字符串表示可能不一致(例如,绝对路径 vs 相对路径,或大小写差异)。__file__ 返回的是字符串,而 each 是 Path 对象,直接转换为字符串后可能不匹配。

解决方案:改用 Path 对象进行精确比较。修改 get_files 函数中的检查条件。

问题2:为什么 files.remove(__file__) 无法删除本程序文件?
这是因为 files 列表中的元素是 Path 对象,而 __file__ 是字符串。在 Python 中,不同类型对象即使路径相同,也不会被视为相等,因此 remove() 方法找不到匹配项。

解决方案:在删除时使用 Path 对象,或先将列表元素转换为字符串。

以下是修改后的代码示例,解决上述问题:


  1. from pathlib import Path

  2. def get_files(p, files):
  3.     current_file = Path(__file__)  # 将当前文件路径转为 Path 对象
  4.     for each in p.iterdir():
  5.         if each == current_file:  # 直接比较 Path 对象
  6.             continue
  7.         if each.is_file() and each.suffix == '.py':
  8.             files.append(each)
  9.         if each.is_dir():
  10.             get_files(each, files)  # 递归时传递当前目录
  11.     return files

  12. def count_lines(files):
  13.     lines = 0
  14.     for each in files:
  15.         with open(each, "r", errors="ignore") as f:
  16.             t = f.readlines()
  17.             lines += len(t) - t.count('\n')
  18.     return lines

  19. p = Path.cwd()
  20. files = []  # 初始化空列表
  21. files = get_files(p, files)

  22. # 如果需要额外删除本程序文件(通常不需要,因为函数已跳过)
  23. # 可以使用:files.remove(Path(__file__))

  24. for each in files:
  25.     print(each)
  26. # print(f"一个有 {count_lines(files)} 行代码~")
复制代码


关键修改点:
- 在 get_files 中,使用 Path(__file__) 创建当前文件的 Path 对象,并通过 each == current_file 进行比较。
- 递归调用时,直接传递 each(目录路径),避免修改原 p
- 初始化 files 为空列表。

这样修改后,列表将正确跳过本程序文件,且删除操作(如需要)应使用 Path 对象。如果还有疑问,请随时提出!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-10-18 14:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表