2015-05-17 92 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,這可能有助於避免混淆。

相關問題