2015-05-17 94 views
0

我想在包含几个子目录(如'20150516')的目录'excercise'下的所有文件中搜索关键字。os.path.isfile(file_path)当file_path是相对路径时返回false,为什么?

这里是我的代码:()

import os,sys,view_all 

def search_special(file): 
    with open(file,'r') as fp: 
     while 1: 
      line = fp.readline() 
      if len(line) == 0: 
       break 
      if 'KeyboardInterrupt' in line: 
       res.append(file) 
       break 
    if not (file in res): 
     print "%s has no keyword 'KeyboardInterrupt'"%file 

def traver_path(main_dir): 
    for path_name in os.listdir(main_dir): 
     current_dir = os.path.abspath(main_dir) 
     recursive_dir = os.path.join(current_dir,path_name) 
     if os.path.isdir(recursive_dir): 
      traver_path(recursive_dir) 
     if os.path.isfile(recursive_dir): 
      if path_name[-3:] == '.py': 
       search_special(recursive_dir) 


if __name__ == "__main__": 
    res = [] 
    traver_path('.') 
    # print res 
    for item in res: 
     view_all.print_file(item) 

而且效果很好。但是,如果我做一个小小的改变FUNC traver_path像:

def traver_path(main_dir): 
    for path_name in os.listdir(main_dir): 
     if os.path.isdir(path_name): 
      traver_path(os.path.join(os.path.abspath(main_dir),path_name)) 
     if os.path.isfile(path_name): 
      if path_name[-3:] == '.py': 
       search_special(os.path.join(os.path.abspath(main_dir),path_name)) 

注意,对于os.path.isdir和os.path.isfile参数已经被改变(不再是ABSPATH)

我当我通过pdb调试时发现了一些有趣的东西。

(Pdb) 
> /Users/Crayon_277/Develop/Project/Python/exercise/view_special.py(27)traver_path() 
-> if os.path.isdir(path_name): 
(Pdb) p path_name 
'20150507' 
(Pdb) n 
> /Users/Crayon_277/Develop/Project/Python/exercise/view_special.py(28)traver_path() 
-> traver_path(os.path.join(os.path.abspath(main_dir),path_name)) 

获取到子目录20150507

(Pdb) p path_name 
'common_divisor.py' 
(Pdb) n 
> /Users/Crayon_277/Develop/Project/Python/exercise/view_special.py(29)traver_path() 
-> if os.path.isfile(path_name): 
(Pdb) s 
--Call-- 
> /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/genericpath.py(26)isfile() 
-> def isfile(path): 
(Pdb) return 
--Return-- 
> /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/genericpath.py(31)isfile()->False 
-> return False 

返回false,这应该是真实的,导致common_divisor.py 文件。

另一项测试:

>>> for i in os.listdir('.'): 
...  print i,str(os.path.isfile(i)) 
... 
.DS_Store True 
.view_all.py.swp True 
.view_special.py.swp True 
20150506 False 
20150507 False 
20150509 False 
20150510 False 
20150511 False 
20150512 False 
20150513 False 
20150514 False 
20150516 False 
view_all.py True 
view_all.pyc True 
view_special.py True 
>>> for i in os.listdir('./20150509'): 
...  print i,str(os.path.isfile(i)) 
... 
bibao.py False 
chinese_test.py False 
decorate.py False 
encrypt.py False 
isinstance_test.py False 
python3_test.py False 

我是来与比相对路径ABSPATH os.path.isfile更好的作品正确的结论?

为什么?

+2

你知不知道所有这些都可以通过简单地使用['grep'](http://linux.die.net/man/1/grep)来避免? – MattDMo

+0

@MattDMo号但是grep是一个shell命令?你可以再详细一点吗? – MMMMMCCLXXVII

+0

你也可以使用'os.walk()' –

回答

0

作为我的研究,关键是你开始程序的目录。

让我们PDB的isfile函数,

(Pdb) 
> /Users/Crayon_277/Develop/Project/Python/exercise/view_special.py(29)traver_path() 
-> if os.path.isfile(path_name): 
(Pdb) s 
--Call-- 
> /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/genericpath.py(26)isfile() 
-> def isfile(path): 
(Pdb) 
> /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/genericpath.py(28)isfile() 
-> try: 
(Pdb) 
> /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/genericpath.py(29)isfile() 
-> st = os.stat(path) 
(Pdb) 
OSError: (2, 'No such file or directory', 'common_divisor.py') 
> /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/genericpath.py(29)isfile() 
-> st = os.stat(path) 
(Pdb) 
> /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/genericpath.py(30)isfile() 
-> except os.error: 
(Pdb) 
> /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/genericpath.py(31)isfile() 
-> return False 

好了,现在我们知道特定的错误, “没有这样的文件或目录”。 但是traver_path(os.path.join(os.path.abspath(main_dir),path_name)),我没有将完整路径传递给递归函数traver_path。所以这就是要点。我在“root”目录中启动了该程序,其中的isfile func基于此目录。

os.path.isfile(path_name) 

如果路径名不是一个ABSPATH,蟒蛇认为这将是“根”目录下,因为它就像“common_divisor.py”一个海峡,即使我设定的参数递归函数。

另一种选择:使用os.walk这样

def traver_dir(main_dir): 
    for root,dirs,files in os.walk(main_dir): 
     for file in files: 
      if file[-3:] == '.py': 
       search_special(root+'/'+file) 
0

你确实应该使用os.walk()您的特定需求。此外,请注意当您尝试执行os.listdir('some_directory')时 - 您得到的是名称列表。 os.path.isfile(x)为False的原因是 - 这些名称是而不是当前目录中的文件。因此,当您为os.listdir('.')(current_directory)执行此操作时为true,但在执行os.listdir('./20150509')时不会。相当于它的一个bash将是ls ./20150509然后说ls bibao.py,显然第二个将显示'没有这样的文件或目录'。您可能需要先尝试os.path.exists,这可能有助于避免混淆。

相关问题