2015-05-17 3 views
0

Я хочу найти ключевое слово во всем файле под моим каталогом «excercise», который содержит несколько подкаталогов, например «20150516».os.path.isfile (file_path) возвращает false, когда file_path является относительным путем, почему?

Вот мой код:()

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 

Возвращение Ложные, которое должно быть правдой, причиной 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 

Могу ли я прийти к правильному выводу, что os.path.isfile лучше работает с abspath, чем относительный путь?

И ПОЧЕМУ?

+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. Так вот в чем дело. Я начал программу в корневой директории, на которой основано isfile func.

os.path.isfile(path_name) 

Если 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 - эти имена не файлов в текущем каталоге. Следовательно, вы получите True, когда вы делаете это для os.listdir('.') (current_directory), но не тогда, когда вы делаете os.listdir('./20150509'). Бах-эквивалент этого будет ls ./20150509, а затем скажет ls bibao.py, очевидно, второй покажет «Нет такого файла или каталога». Вы можете сначала попробовать os.path.exists, который может помочь и избежать путаницы.

Смежные вопросы