对python os.path.abspath的误解

时间:2014-07-11 20:05:59

标签: python path os.path

我有以下代码:

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

我想要下一个输出:

  • d:\ IMAGES \ img1.jpg
  • D:\ images \ img2.jpg等等

但我得到了不同的结果:

  • d:\代码\ img1.jpg
  • d:\代码\ img2.jpg

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

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

所以,问题是:当我必须使用

时,os.path.abspath的目的是什么
os.path.normpath(os.path.join(directory, file))

获取我文件的REAL绝对路径?尽可能显示真实的用例。

3 个答案:

答案 0 :(得分:32)

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

img1.jpg
img2.jpg
...

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

的原因

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

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

答案 1 :(得分:5)

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

os.chdir(directory)
for f in os.listdir('.'):
    print(os.path.abspath(f))

答案 2 :(得分:3)

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前进)。这些会为项目添加依赖项,但会在文件,文件名和文件路径处理的许多方面进行升级。