鱼C论坛

 找回密码
 立即注册
查看: 539|回复: 8

[已解决]第30讲2号题目小问题求助~~

[复制链接]
发表于 2019-2-2 11:01:16 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 whiteyetihw 于 2019-2-2 11:02 编辑

题目:2. 编写一个程序,用户输入文件名以及开始搜索的路径,搜索该文件是否存在。如遇到文件夹,则进入文件夹继续搜索,程序实现如图:
以下是小甲鱼老师的代码:~
  1. import os

  2. def search_file(start_dir, target) :
  3.     os.chdir(start_dir)
  4.    
  5.     for each_file in os.listdir(os.curdir) :
  6.         if each_file == target :
  7.             print(os.getcwd() + os.sep + each_file) # 使用os.sep是程序更标准
  8.         if os.path.isdir(each_file) :
  9.             search_file(each_file, target) # 递归调用
  10.             os.chdir(os.pardir) # 递归调用后切记返回上一层目录

  11. start_dir = input('请输入待查找的初始目录:')
  12. target = input('请输入需要查找的目标文件:')
  13. search_file(start_dir, target)
复制代码


问题:为什么06行的os.curdir改成start_dir会报错??当前情况下的os.curdir和start_dir不应该是一样的吗??
最佳答案
2019-2-2 12:41:55
本帖最后由 jackz007 于 2019-2-2 12:57 编辑

      因为这个脚本的设计有一个基本前提,文件搜索在相对路径下进行,所以,在函数递归中用到了 os . curdir()、os . getcwd()、os . chdir() 等一系列配套函数,当然,完全可以改成基于绝对路径的搜索,就像楼主所愿,把 os . curdir() 改成 start_dir,但是,这需要对其他代码进行相应的修改:

  1. #!/bin/python
  2. #coding:gbk

  3. import os

  4. def search_file(start_dir , target) :
  5.     try :     # 执行下一条语句存在异常风险,加入 try 语句可以处理异常,避免程序意外地退出
  6.         for each_file in os . listdir(start_dir) :    # 在 Windows 下,当 start_dir 为无权限路径时,执行该语句会发生异常
  7.             each_file_with_path = start_dir + os . sep + each_file
  8.             if (start_dir[-1] == os . sep) :
  9.                 each_file_with_path = start_dir + each_file
  10.             if each_file . upper() == target . upper() :    # Windows 文件名比较忽略字母大小写
  11.                 print(each_file_with_path)    # 使用 os.sep 使程序更标准
  12.             if os . path . isdir(each_file_with_path) :
  13.                 search_file(each_file_with_path , target)    # 递归调用
  14.     except :    # 如果异常发生,就直接从此处继续执行
  15.         pass     #  什么都不做

  16. start_dir = raw_input('请输入待查找的初始目录:') . strip()
  17. target = raw_input('请输入需要查找的目标文件:') . strip()
  18. search_file(start_dir, target)
复制代码


       加入 try 语句,是为了避免在 Windows 系统下,搜索到没有权限的目录,脚本会出错;在 target 比较中加入 upper() 是为了忽略文件名的大小写铭感。

      以下是该脚本在 Python 2.7.13 环境中的运行情况:

G:\[2019]\00.00.Exercise\Python\Searchfile>python Searchfile.py
请输入待查找的初始目录:C:\
请输入需要查找的目标文件:NoTePaD.ExE
C:\Windows\notepad.exe
C:\Windows\System32\notepad.exe
C:\Windows\SysWOW64\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepadwin_31bf3856ad364e35_6.1.7600.1
6385_none_9ebebe8614be1470\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepadwin_31bf3856ad364e35_6.1.7601.1
8917_none_a0f2c3fc11a9f24c\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepadwin_31bf3856ad364e35_6.1.7601.2
3120_none_a16a66f72ad62fe8\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7600.1638
5_none_cb0f7f2289b0c21a\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7601.1891
7_none_cd438498869c9ff6\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7601.2312
0_none_cdbb27939fc8dd92\notepad.exe
C:\Windows\winsxs\wow64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7600.1638
5_none_d5642974be118415\notepad.exe
C:\Windows\winsxs\wow64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7601.1891
7_none_d7982eeabafd61f1\notepad.exe
C:\Windows\winsxs\wow64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7601.2312
0_none_d80fd1e5d4299f8d\notepad.exe

G:\[2019]\00.00.Exercise\Python\Searchfile>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-2-2 11:22:02 | 显示全部楼层
输出下就知道了
os.curdir在Windows 下是个 常量 .
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-2-2 12:07:25 | 显示全部楼层
zlj19931010 发表于 2019-2-2 11:22
输出下就知道了
os.curdir在Windows 下是个 常量 .

诶,不好意思没太懂呀
我知道他是常量. 所以可以得出什么结论呢
能再解释一下吗【捂脸】
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-2 12:41:55 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2019-2-2 12:57 编辑

      因为这个脚本的设计有一个基本前提,文件搜索在相对路径下进行,所以,在函数递归中用到了 os . curdir()、os . getcwd()、os . chdir() 等一系列配套函数,当然,完全可以改成基于绝对路径的搜索,就像楼主所愿,把 os . curdir() 改成 start_dir,但是,这需要对其他代码进行相应的修改:

  1. #!/bin/python
  2. #coding:gbk

  3. import os

  4. def search_file(start_dir , target) :
  5.     try :     # 执行下一条语句存在异常风险,加入 try 语句可以处理异常,避免程序意外地退出
  6.         for each_file in os . listdir(start_dir) :    # 在 Windows 下,当 start_dir 为无权限路径时,执行该语句会发生异常
  7.             each_file_with_path = start_dir + os . sep + each_file
  8.             if (start_dir[-1] == os . sep) :
  9.                 each_file_with_path = start_dir + each_file
  10.             if each_file . upper() == target . upper() :    # Windows 文件名比较忽略字母大小写
  11.                 print(each_file_with_path)    # 使用 os.sep 使程序更标准
  12.             if os . path . isdir(each_file_with_path) :
  13.                 search_file(each_file_with_path , target)    # 递归调用
  14.     except :    # 如果异常发生,就直接从此处继续执行
  15.         pass     #  什么都不做

  16. start_dir = raw_input('请输入待查找的初始目录:') . strip()
  17. target = raw_input('请输入需要查找的目标文件:') . strip()
  18. search_file(start_dir, target)
复制代码


       加入 try 语句,是为了避免在 Windows 系统下,搜索到没有权限的目录,脚本会出错;在 target 比较中加入 upper() 是为了忽略文件名的大小写铭感。

      以下是该脚本在 Python 2.7.13 环境中的运行情况:

G:\[2019]\00.00.Exercise\Python\Searchfile>python Searchfile.py
请输入待查找的初始目录:C:\
请输入需要查找的目标文件:NoTePaD.ExE
C:\Windows\notepad.exe
C:\Windows\System32\notepad.exe
C:\Windows\SysWOW64\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepadwin_31bf3856ad364e35_6.1.7600.1
6385_none_9ebebe8614be1470\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepadwin_31bf3856ad364e35_6.1.7601.1
8917_none_a0f2c3fc11a9f24c\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepadwin_31bf3856ad364e35_6.1.7601.2
3120_none_a16a66f72ad62fe8\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7600.1638
5_none_cb0f7f2289b0c21a\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7601.1891
7_none_cd438498869c9ff6\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7601.2312
0_none_cdbb27939fc8dd92\notepad.exe
C:\Windows\winsxs\wow64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7600.1638
5_none_d5642974be118415\notepad.exe
C:\Windows\winsxs\wow64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7601.1891
7_none_d7982eeabafd61f1\notepad.exe
C:\Windows\winsxs\wow64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7601.2312
0_none_d80fd1e5d4299f8d\notepad.exe

G:\[2019]\00.00.Exercise\Python\Searchfile>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-2-2 13:03:28 | 显示全部楼层
jackz007 发表于 2019-2-2 12:41
因为这个脚本的设计有一个基本前提,文件搜索在相对路径下进行,所以,在函数递归中用到了 os . curd ...

好厉害!多谢多谢
还想再问一句:
在语句 for each_file in os.listdir(os.curdir): 中 按照【os.listdir()】的定义,这里的【each】应该只是文件名
,为什么又可以作为路径成为递归调用的第一个参数呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-2 13:12:08 | 显示全部楼层
本帖最后由 jackz007 于 2019-2-2 13:14 编辑
whiteyetihw 发表于 2019-2-2 13:03
好厉害!多谢多谢
还想再问一句:
在语句 for each_file in os.listdir(os.curdir): 中 按照 ...


    因为 each 只是子目录名和文件名,不含绝对路径,例如,

  1. for each in os.listdir('C:\\Windows')
复制代码


    each 可以是 'System32'、'notepad.exe' 等等,但是,如果把 each 直接作为递归的第一个参数,就像这样:

  1. search_file('System32' , target)
复制代码


    它能正常执行吗,除非当前路径是 "C:\\Wondows" 才可以。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-2-2 15:32:03 | 显示全部楼层
jackz007 发表于 2019-2-2 13:12
因为 each 只是子目录名和文件名,不含绝对路径,例如,

emm所以按理是不可以正常执行的鸭【捂脸】,可是给的标准题解是可以的,所以很懵逼还是不知道是为啥可以

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-2 15:48:46 | 显示全部楼层
本帖最后由 jackz007 于 2019-2-2 16:09 编辑
whiteyetihw 发表于 2019-2-2 15:32
emm所以按理是不可以正常执行的鸭【捂脸】,可是给的标准题解是可以的,所以很懵逼还是不知道是为啥可以{ ...


       打个比方,如果你在新疆乌鲁木齐寄信,目标地址是,"本市经济技术开发区" 邮递员可以通过寄信地址 + 目标地址顺利地把信投到。如果你在国外寄信,目的地址上写的却只是"经济技术开发区",你的信还能投到吗?是不是得写上”中国新疆乌鲁木齐经济技术开发区” 才行?目的地是同一个,区别是前者使用相对路径表述,而后者使用绝对路径表述。

      不论是 Windows 还是 Linux 系统,路径都是分相对路径和绝对路径的,相对路径是从当前路径起算的路径,通过借用当前路径可以得到绝对路径。

      例如,如果当前路径是 'C:\\Windows' 那么,相对路径 'System32\\notepad.exe' 的绝对路径就是 'C:\\Windows' + '\\' + 'System32\\noetpad.exe' 结果得到: 'C:\\Windows\\System32\\notepad.exe'

      所以,无论哪种路径,最终都必须落实为绝对路径,操作系统才能够定位到目标。

      你的原始程序就是通过相对路径来搜索文件的,所以才要不断利用 os . chdir() 改变当前路径。而我修改的代码直接使用绝对路径,所以就一次都没有用到这个函数。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2019-2-2 16:06:44 | 显示全部楼层
jackz007 发表于 2019-2-2 15:48
不论是 Windows 还是 Linux 系统,路径都是分相对路径和绝对路径的,相对路径是从当前路径起算的 ...

明白了,多谢十分耐心的dalao~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-13 03:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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