为何递归后必须返回上级目录
论坛上面有人问答这个问题,但是一直没看懂,求大神不吝赐教,import os
def search_file(path,tp):
os.chdir(path)
file_all=os.listdir(os.curdir)
for file_each in file_all:
if os.path.isdir(file_each):
search_file(file_each,tp)
## os.chdir(os.pardir)
if os.path.splitext(file_each)=="."+tp:
print(os.path.realpath(file_each))
path=input("请输入查找的初始目录:")
tp=input("请输入查找的文件类型【扩展名】:")
search_file(path,tp)
比如我要查找桌面上名称为1的文件家中包的文本文件(.txt)路径
文件夹1结构如下:
<1>
├123.txt
├<2>
│└123.txt
├<3>
│├123.txt
│├<4>
││└123.txt
注释掉 os.chdir(os.pardir)后结果明显不正常。
结果如下:
请输入查找的初始目录:d:\desktop\1
请输入查找的文件类型【扩展名】:txt
d:\desktop\1\123.txt
d:\desktop\1\2\123.txt
从运行过程来看,递归进入子文件夹2后,返回,继续运行 for for file_each in file_all:
file_each的值变为“3”,但接下来并未执行 if os.path.isdir(file_each) 或者认为判断为False,
所以就直接跳转至 if os.path.splitext(file_each)=="."+tp: 然后就没有然后了。
感觉程序直接将文件夹3当成文件了,根本没有触及其内部文件及子文件夹。那么为什么
文件夹2可以递归而文件3就不行了呢?把文件夹3命名为文件夹0,文件夹0可以递归,文件夹2
又不行了。为什么呢?难道就是一条路走到黑,回来后就六亲不认了吗? 本帖最后由 jackz007 于 2020-3-23 00:05 编辑
因为在递归调用的时候,在函数入口,通过
def search_file(path,tp):
os.chdir(path)
无条件地把当前路径改变到次级子目录中了,而在函数退出的时候,却没有相应返回父目录的操作,因此,在递归调用前后,当前目录会发生改变。而这种改变会直接影响到后续子目录、文件的识别及子目录递归,导致函数无法正常运行。所以,在递归调用之后,必须通过下面的语句
search_file(file_each,tp)
os.chdir(os.pardir)
把当前目录修改为父目录,其实,这是在恢复递归调用前的环境和状态,消除因函数递归调用而带来的有害改变,所以,这个操作是非常必要的!
楼主可以试试修改的代码:
import os
def search_file(path , tp):
cd = os . getcwd()
os . chdir(path)
try:
for file_each in os . listdir() :
if os . path . isdir(file_each) :
search_file(file_each , tp)
elif os . path . isfile(file_each) :
if os . path . splitext(file_each) . lower() == tp . lower() :
print(os . path . realpath(file_each))
except:
pass
os . chdir(cd)
path = input("请输入查找的初始目录:") . strip()
if path :
if os . path . exists(path) and os . path . isdir(path) :
tp = input("请输入查找的文件类型【扩展名】:") . strip()
if tp :
if tp != '.' : tp = '.' + tp
search_file(path , tp) jackz007 发表于 2020-3-22 23:26
因为在递归调用的时候,在函数入口,通过
无条件地把当前路径改变到次级子目录中了,而在函 ...
当for语句循序至file_each=“3”(3是文件夹)时, 加上os.chdir(os.pardir)这行代码和注释掉这行代码,
vs code变量窗口看到的内容是完全相同的。
(return)abspath: 'd:\\desktop\\1\\123.txt'
file_all:['123.txt','2','3']
file_each:'3'
path:'d:\\desktop\\1'
(return) search_file:none
(return)splitext;('2','')
tp:'txt'
那么为什么接着运行,结果却不一样呢? yeahwsw 发表于 2020-3-23 10:27
当for语句循序至file_each=“3”(3是文件夹)时, 加上os.chdir(os.pardir)这行代码和注释掉这行代码,
...
完全听不懂你在说什么,这么说吧,你是否接受递归后返回父目录的必要性?不要纠缠和讨论错误的代码,因为没有任何意义,除非,你确定自己每次都会在这里摔倒!!! jackz007 发表于 2020-3-23 10:55
完全听不懂你在说什么,这么说吧,你是否接受递归后返回父目录的必要性?不要纠缠和讨论错误的代 ...
虽然没能解释我的问题,但是还是要谢谢你
页:
[1]