30

我有以下代码:

directory = r'D:\images'
for file in os.listdir(directory):
    print(os.path.abspath(file))

我想要下一个输出:

  • D:\图像\img1.jpg
  • D:\images\img2.jpg 等等

但我得到不同的结果:

  • D:\code\img1.jpg
  • D:\code\img2.jpg

其中 D:\code 是我当前的工作目录,此结果与

os.path.normpath(os.path.join(os.getcwd(), file))

所以,问题是:我必须使用 os.path.abspath 的目的是什么

os.path.normpath(os.path.join(directory, file))

获取我的文件的真实绝对路径?如果可能,展示真实的用例。

4

3 回答 3

40

问题在于您对os.listdir()not的理解os.path.abspath()os.listdir()返回目录中每个文件的名称。这会给你:

img1.jpg
img2.jpg
...

当您将这些传递给 时os.path.abspath(),它们被视为相对路径。这意味着它与您执行代码的目录相关。这就是你得到“D:\code\img1.jpg”的原因。

相反,您要做的是将文件名与您列出的目录路径连接起来。

os.path.abspath(os.path.join(directory, file))
于 2014-07-11T20:12:53.070 回答
6

listdir目录中生成文件名,而不参考目录本身的名称。没有任何其他信息,abspath只能从它可以知道的唯一目录形成绝对路径:当前工作目录。您始终可以在循环之前更改工作目录:

os.chdir(directory)
for f in os.listdir('.'):
    print(os.path.abspath(f))
于 2014-07-11T20:12:02.157 回答
4

Python 的本机os.listdiros.path函数非常低级。遍历一个目录(或一系列降序目录)需要您的程序手动组装文件路径。定义一个实用函数来生成您只需要一次的路径会很方便,这样路径组装逻辑就不必在每次目录迭代中重复。例如:

import os

def better_listdir(dirpath):
    """
    Generator yielding (filename, filepath) tuples for every
    file in the given directory path.
    """
    # First clean up dirpath to absolutize relative paths and
    # symbolic path names (e.g. `.`, `..`, and `~`)
    dirpath = os.path.abspath(os.path.expanduser(dirpath))

    # List out (filename, filepath) tuples
    for filename in os.listdir(dirpath):
        yield (filename, os.path.join(dirpath, filename))

if __name__ == '__main__':
    for fname, fpath in better_listdir('~'):
        print fname, '->', fpath

或者,可以使用“更高级别”的路径模块,例如py.pathpath.pypathlib(现在是 Python 的标准部分,适用于 3.4 及更高版本,但可用于 2.7 向前版本)。这些向您的项目添加了依赖项,但提升了文件、文件名和文件路径处理的许多方面。

于 2014-07-11T20:59:03.700 回答