【问题标题】:os.path.isfile(file_path) return false when file_path is a relative path, why?当 file_path 是相对路径时,os.path.isfile(file_path) 返回 false,为什么?
【发布时间】:2015-05-17 03:50:28
【问题描述】:

我想在我的目录“excercise”下的所有文件中搜索关键字,该目录包含多个子目录,例如“20150516”。

这是我的代码:()

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 的参数已更改。(不再是绝对路径)

当我通过 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,应该是True,导致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 使用绝对路径比使用相对路径更好?

为什么?

【问题讨论】:

  • 您知道吗?只需使用grep 就可以避免所有这些?
  • @MattDMo 不。但是 grep 是一个 shell 命令吗?你能说得更具体一点吗?
  • 你也可以使用os.walk()
  • 您是否点击了我提供的链接? grep 是大多数 Unix 和 Linux 平台上可用的实用程序,包括 OS X(我假设您根据路径名使用它)。该链接提供了有关如何使用它的所有详细信息,或者您可以在终端中输入man grep
  • @MattDMo 谢谢。明白了

标签: python


【解决方案1】:

根据我的研究,关键是您启动程序的目录。

让我们 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,python 认为它会在“root”目录下,因为它只是一个类似于“common_divisor.py”的 str,即使我将参数设置为递归函数。

另一种选择:像这样使用 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)

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-16
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 2010-11-27
      • 2023-04-02
      相关资源
      最近更新 更多