2

我在网站上阅读了很多链接说要使用“os.path.abspath(#filename)”。这种方法并不完全适合我。我正在编写一个程序,该程序将能够在给定目录中搜​​索具有某些扩展名的文件,将名称和绝对路径作为键和值(分别)保存到字典中,然后使用绝对路径打开文件并制作所需的编辑。我遇到的问题是,当我使用 os.path.abspath() 时,它没有返回完整路径。

假设我的程序在桌面上。我有一个文件存储在“C:\Users\Travis\Desktop\Test1\Test1A\test.c”。我的程序可以轻松找到此文件,但是当我使用 os.path.abspath() 时,它返回“C:\Users\Travis\Desktop\test.c”,这是存储我的源代码的绝对路径,但不是我正在搜索的文件。

我的确切代码是:

import os
Files={}#Dictionary that will hold file names and absolute paths
root=os.getcwd()#Finds starting point
for root, dirs, files in os.walk(root):
    for file in files:
        if file.endswith('.c'):#Look for files that end in .c
            Files[file]=os.path.abspath(file)

关于它为什么会这样做以及如何解决它的任何提示或建议?提前致谢!

4

3 回答 3

6

os.path.abspath()使相对路径绝对相对于当前工作目录,而不是文件的原始位置。路径只是一个字符串,Python 无法知道文件名的来源。

您需要自己提供目录。当您使用 时os.walk,每次迭代都会列出列出的目录(root在您的代码中)、子目录列表(只是它们的名称)和文件名列表(同样,只是它们的名称)。与文件名一起使用root以创建绝对路径:

Files={}
cwd = os.path.abspath(os.getcwd())
for root, dirs, files in os.walk(cwd):
    for file in files:
        if file.endswith('.c'):
            Files[file] = os.path.join(root, os.path.abspath(file))

请注意,您的代码仅记录每个唯一文件名的一个路径;如果你有foo/bar/baz.cfoo/spam/baz.c,这取决于操作系统列出的顺序barspam两条路径之一获胜的子目录。

您可能希望将路径收集到列表中:

Files={}
cwd = os.path.abspath(os.getcwd())
for root, dirs, files in os.walk(cwd):
    for file in files:
        if file.endswith('.c'):
            full_path = os.path.join(root, os.path.abspath(file))
            Files.setdefault(file, []).append(full_path)
于 2014-05-16T13:51:11.327 回答
0

根据os.path.join 的文档

如果任何组件是绝对路径,则所有先前的组件(在 Windows 上,包括先前的驱动器号,如果有的话)都将被丢弃

因此,例如,如果第二个参数是绝对路径,'/a/b/c'则丢弃第一个路径。

In [14]: os.path.join('/a/b/c', '/d/e/f')
Out[14]: '/d/e/f'

所以,

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

root不管它是什么都将丢弃,并返回os.path.abspath(file)哪个将附加file到当前工作目录,这不一定与root.

相反,要形成文件的绝对路径:

fullpath = os.path.abspath(os.path.join(root, file))

实际上os.path.abspath认为. root_ 因此,为了绝对确定(双关语),请使用.os.walkos.walkos.path.abspath


import os
samefiles = {}
root = os.getcwd()
for root, dirs, files in os.walk(root):
    for file in files:
        if file.endswith('.c'):
            fullpath = os.path.join(root, file)
            samefiles.setdefault(file, []).append(fullpath) 

print(samefiles)
于 2014-05-16T14:55:49.833 回答
-1

Glob 在这些情况下很有用,你可以这样做:

files = {f:os.path.join(os.getcwd(), f) for f in glob.glob("*.c")}

得到相同的结果

于 2014-05-16T14:02:50.210 回答