简体   繁体   English

您如何在Python中获取文件的绝对路径?

[英]How do you get the absolute path of a file in Python?

I have read quite a few links on the site saying to use "os.path.abspath(#filename)". 我已经在网站上阅读了很多链接,说使用“ os.path.abspath(#filename)”。 This method isn't exactly working for me. 这种方法并不适合我。 I am writing a program that will be able to search a given directory for files with certain extensions, save the name and absolute path as keys and values (respectively) into a dictionary, and then use the absolute path to open the files and make the edits that are required. 我正在编写一个程序,该程序将能够在给定目录中搜​​索具有某些扩展名的文件,将名称和绝对路径分别作为键和值保存到字典中,然后使用绝对路径打开文件并创建所需的编辑。 The problem I am having is that when I use os.path.abspath() it isn't returning the full path. 我遇到的问题是,当我使用os.path.abspath()时,它没有返回完整路径。

Let's say my program is on the desktop. 假设我的程序在桌面上。 I have a file stored at "C:\\Users\\Travis\\Desktop\\Test1\\Test1A\\test.c". 我有一个文件存储在“ C:\\ Users \\ Travis \\ Desktop \\ Test1 \\ Test1A \\ test.c”。 My program can easily locate this file, but when I use os.path.abspath() it returns "C:\\Users\\Travis\\Desktop\\test.c" which is the absolute path of where my source code is stored, but not the file I was searching for. 我的程序可以轻松找到该文件,但是当我使用os.path.abspath()时,它将返回“ C:\\ Users \\ Travis \\ Desktop \\ test.c”,这是我的源代码存储的绝对路径,但不是我正在搜索的文件。

My exact code is: 我的确切代码是:

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)

Any tips or advice as to why it may be doing this and how I can fix it? 关于它为什么这样做以及如何解决的任何提示或建议? Thanks in advance! 提前致谢!

os.path.abspath() makes a relative path absolute relative to the current working directory , not to the file's original location. os.path.abspath()使相对路径相对于当前工作目录为绝对路径,而不是相对于文件的原始位置。 A path is just a string, Python has no way of knowing where the filename came from. 路径只是一个字符串,Python无法知道文件名来自何处。

You need to supply the directory yourself. 您需要自己提供目录。 When you use os.walk , each iteration lists the directory being listed ( root in your code), the list of subdirectories (just their names) and a list of filenames (again, just their names). 当您使用os.walk ,每次迭代都会列出所列出的目录(代码中的root ),子目录列表(仅是它们的名称)和文件名列表(同样是它们的名称)。 Use root together with the filename to make an absolute path: 结合使用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))

Note that your code only records the one path for each unique filename; 请注意,您的代码仅记录每个唯一文件名的一个路径; if you have foo/bar/baz.c and foo/spam/baz.c , it depends on the order the OS listed the bar and spam subdirectories which one of the two paths wins. 如果您拥有foo/bar/baz.cfoo/spam/baz.c ,则取决于操作系统列出的barspam子目录的顺序,两条路径中的其中一个会获胜。

You may want to collect paths into a list instead: 您可能希望将路径收集到列表中:

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)

Per the docs for os.path.join , 根据os.path.join的文档

If any component is an absolute path, all previous components (on Windows, including the previous drive letter, if there was one) are thrown away 如果任何组件都是绝对路径,则所有先前的组件(在Windows上,包括先前的驱动器号,如果有的话)都将被丢弃。

So, for example, if the second argument is an absolute path, the first path, '/a/b/c' is discarded. 因此,例如,如果第二个参数是绝对路径,则第一个路径'/a/b/c'被丢弃。

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

Therefore, 因此,

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

will discard root no matter what it is, and return os.path.abspath(file) which will tack file on to the current working directory, which will not necessarily be the same as root . 无论它是什么,都将丢弃root ,并返回os.path.abspath(file) ,它将file os.path.abspath(file)到当前工作目录上,该目录不一定与root相同。

Instead, to form the absolute path to the file: 相反,形成文件的绝对路径:

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

Actually, I believe the os.path.abspath is unnecessary, since I believe root will always be absolute, but my reasoning for that depends on the source code for os.walk not just the documented (guaranteed) behavior of os.walk . 其实,我相信os.path.abspath是不必要的,因为我相信, root永远是绝对的,但我对这种推理取决于对源代码os.walk不仅仅是记录(保证)的行为os.walk So to be absolutely sure (pun intended), use os.path.abspath . 因此,要完全确定(双关语),请使用os.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)

Glob is useful in these cases, you can do: 在这些情况下,Glob很有用,您可以执行以下操作:

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

to get the same result 得到相同的结果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM