如何获取当前文件目录的完整路径?

1435

如何获取当前文件的目录路径?我尝试了:

>>> os.path.abspath(__file__)
'C:\\python27\\test.py'

但我想要:

'C:\\python27\\'

7
可能是重复的问题:查找当前目录和文件目录 - user2284570
14
当您将Python作为交互式Shell运行时,会出现“__file__未定义”的错误。您问题中的第一段代码看起来像来自一个交互式Shell,但实际上会产生NameError错误,至少在Python 2.7.3版本上会出现这个问题,其他版本也可能会有此问题。 - drevicko
4
为什么这个如此困难?关于这个话题,SO上有许多篇帖子。Python:“简洁胜于复杂......应该有一种明显的方法来做到这一点,最好只有一种。” - eric
os.path.split(file_path)[0] - Super Mario
1
@eric 这并不难,而且多个问题的存在并不意味着某些东西很难 - 这是人们没有做好研究的证据,问题标题对于SEO来说不够优化,或者人们未能关闭应该关闭的重复问题。 - Karl Knechtel
print(os.getcwd()) - undefined
12个回答

2676

特殊变量 __file__ 包含当前文件的路径。通过使用 pathlibos.path 模块,我们可以获取该目录。

Python 3

对于正在运行的脚本所在的目录:

import pathlib
pathlib.Path(__file__).parent.resolve()

对于当前工作目录:

import pathlib
pathlib.Path().resolve()

Python 2 和 3

对于正在运行的脚本所在的目录:

import os
os.path.dirname(os.path.abspath(__file__))

如果您指的是当前工作目录:
import os
os.path.abspath(os.getcwd())

请注意,在file之前和之后都有两个下划线,而不是一个。
另外请注意,如果您正在交互式运行或从除文件以外的其他地方加载代码(例如:数据库或在线资源),由于没有“当前文件”的概念,__file__可能未设置。上述答案假定最常见的情况是运行在文件中的Python脚本。

参考资料

  1. Python文档中的pathlib
  2. os.path - Python 2.7, os.path - Python 3
  3. os.getcwd - Python 2.7, os.getcwd - Python 3
  4. __file__变量的含义/作用是什么?

61
如果您不想在Windows上发现奇怪的行为,dirname(file)可能会返回空字符串,那么abspath()是必需的! - sorin
4
应该是os.path.dirname(os.path.abspath(os.file))吗? - DrBailey
6
@DrBailey:不,ActivePython并没有什么特别之处。__file__(请注意它两边都有两个下划线)是Python的标准组成部分。例如在基于C的模块中就无法使用它,但在Python脚本中它应该总是可用的。 - Bryan Oakley
12
我建议使用realpath代替abspath去解析可能的符号链接,以获得更好的效果。 - TTimo
17
只有在脚本中运行时,这才能起作用。如果从交互式提示符中运行,则没有“__file__”可用。 - Bryan Oakley
显示剩余25条评论

198

使用自Python 3起,pathlib中的Path是推荐的方式:

from pathlib import Path
print("File      Path:", Path(__file__).absolute())
print("Directory Path:", Path().absolute()) # Directory of current working directory, not __file__  

注意:如果使用Jupyter Notebook,__file__无法返回预期的结果,因此必须使用Path().absolute()


33
我需要运行Path(__file__).parent来获取包含该文件的文件夹。 - YellowPillow
1
抱歉,我应该把这个讲得更清楚。如果在位于“path/to/module”的某个模块中存在Path().absolute(),并且您正在从位于“path/to/script”的某个脚本中调用该模块,则会返回path/to/script而不是path/to/module - YellowPillow
1
@YellowPillow Path(__file__).cwd() 更加明确。 - C.W.
3
Path(__file__) 并不总是有效,例如在 Jupyter Notebook 中它无法正常工作。Path().absolute() 可以解决这个问题。 - Ron Kalian
Path(__file__) 在 IDLE 中可以正常工作,但是当我在命令行中执行的 Python 脚本中使用它时,它只会返回脚本的名称而不包括其父级路径...很奇怪...这是一个 bug 吗?我不得不使用 Path(__file__).absolute(),就像你提到的那样,才能显示完整路径。发生在 Python 3.6 中。顺便说一下,在 Python3.6 文档中我没有找到 .absolute() 方法的描述。 - Sun Bear
显示剩余5条评论

108
在Python 3.x中我做:
from pathlib import Path

path = Path(__file__).parent.absolute()

解释:

  • Path(__file__) 是当前文件的路径。
  • .parent 给出了文件所在的目录
  • .absolute() 给出了它的完整绝对路径

使用pathlib是处理路径的现代方法。如果以后需要将其作为字符串使用,请使用str(path)


9
这个答案应该是截至2019年的最佳答案。还可以在答案中提到一件事情:可以立即在Path对象上调用.open(),例如with Path(__file__).parent.joinpath('some_file.txt').open() as f: - stefanct
一些答案存在的另一个问题(例如 Ron Kalian 的答案,如果我没记错的话)是它会给出当前目录,而不一定是 file 路径。 - NotAnAmbiTurner

20

试一试:

import os
dir_path = os.path.dirname(os.path.realpath(__file__))

2
最佳答案。这是我通常获取当前脚本路径的方法,谢谢。 - domih

18
import os
print(os.path.dirname(__file__))

26
抱歉,但这个答案是不正确的,正确答案是由Bryan制作的dirname(abspath(__file__))。有关详细信息,请参阅评论。 - sorin
1
它将输出 / - Abhishek Tripathi
6
实际上在 Python 3.6 中,它们是相同的。 - DollarAkshay

7

我发现以下命令可以返回Python 3脚本的父目录的完整路径。

Python 3脚本:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from pathlib import Path

#Get the absolute path of a Python3.6 and above script.
dir1 = Path().resolve()  #Make the path absolute, resolving any symlinks.
dir2 = Path().absolute() #See @RonKalian answer 
dir3 = Path(__file__).parent.absolute() #See @Arminius answer
dir4 = Path(__file__).parent 

print(f'dir1={dir1}\ndir2={dir2}\ndir3={dir3}\ndir4={dir4}')

注意!!!

  1. dir1dir2 只能在当前工作目录中运行脚本时使用,否则会出错。
  2. 如果 Path(__file__).is_absolute() 的结果是 True,则在 dir3 中使用 .absolute() 方法显得多余。
  3. 可行的最短命令为 dir4

解释链接:.resolve().absolute()Path(file).parent().absolute()


1
一个裸的 Path() 不会 提供脚本/模块目录。它等同于 Path('.') - 当前工作 目录。只有当在当前工作目录中运行脚本时才有效,但在任何其他情况下都会出错。 - MisterMiyagi
@MisterMiyagi,我已经更新了你对我的答案的评论。谢谢。 - Sun Bear

5

如果__file__不可用(jupyter笔记本),也可以正常工作

import sys
from pathlib import Path
path_file = Path(sys.path[0])
print(path_file)

此外还使用了pathlib,它是Python 3中处理路径的面向对象方式。


这个答案是不正确的。sys.path[0]包含了Python解释器的当前工作目录,而不是Python源代码文件所在的目录。详见:https://docs.python.org/3/library/sys.html#sys.path - undefined
@bjmc 是和不是。它在Jupyter笔记本中有效,因为内核的工作目录与笔记本的目录相同。然而,这个答案似乎对人们有帮助,所以我会对其进行修改... - undefined

5

Python中有用的路径属性:

from pathlib import Path

#Returns the path of the current directory
mypath = Path().absolute()
print('Absolute path : {}'.format(mypath))

#if you want to go to any other file inside the subdirectories of the directory path got from above method
filePath = mypath/'data'/'fuel_econ.csv'
print('File path : {}'.format(filePath))

#To check if file present in that directory or Not
isfileExist = filePath.exists()
print('isfileExist : {}'.format(isfileExist))

#To check if the path is a directory or a File
isadirectory = filePath.is_dir()
print('isadirectory : {}'.format(isadirectory))

#To get the extension of the file
fileExtension = mypath/'data'/'fuel_econ.csv'
print('File extension : {}'.format(filePath.suffix))

输出:绝对路径是指您的Python文件所在的路径

绝对路径:D:\Study\Machine Learning\Jupitor Notebook\JupytorNotebookTest2\Udacity_Scripts\Matplotlibseaborn Part2

文件路径:D:\Study\Machine Learning\Jupitor Notebook\JupytorNotebookTest2\Udacity_Scripts\Matplotlibseaborn Part2\data\fuel_econ.csv

文件是否存在:True

是否为目录:False

文件扩展名:.csv


谢谢。在JupyterLab中也完美运行。 - Nils B
5
这是误导性的,绝对路径是指当前工作目录(cwd),而不是您的文件所在位置。不能保证两者相同。 - eric
3
Path() 是当前工作目录,而非脚本所在的目录。这仅在脚本确实位于当前工作目录的少数情况下才“有效”。 - MisterMiyagi

2

Python 2 和 3

你也可以简单地这么做:

from os import sep
print(__file__.rsplit(sep, 1)[0] + sep)

输出结果类似于:

C:\my_folder\sub_folder\

在我刚测试的装有python3.8.10Windows 7机器上,由于某种原因,__file__似乎并没有返回任何路径,而只有文件名。只是提醒其他人注意一下... - Giorgos Xou

0

IPython有一个魔法命令%pwd,可以获取当前工作目录。它可以按以下方式使用:

from IPython.terminal.embed import InteractiveShellEmbed

ip_shell = InteractiveShellEmbed()

present_working_directory = ip_shell.magic("%pwd")

在IPython Jupyter Notebook中,可以直接使用%pwd,如下所示:
present_working_directory = %pwd

8
问题不在于IPython。 - Kiro
4
@Kiro,我的解决方案使用IPython回答了这个问题。例如,如果有人使用一个新的库来回答问题,那么在我看来,它仍然是一个相关的回答。 - Nafeez Quraishi
2
@elli0t,部分同意。考虑到某些使用Jupyter Notebook的人可能会遇到这个问题,他们可能更喜欢使用%pwd魔术命令而不是os import。 - Nafeez Quraishi
1
问题不在于获取当前工作目录,而在于获取脚本的目录。这两者可能非常不同。 - Bryan Oakley
5
我不知道你的意思。问题明确询问文件所在目录的路径,这可能与当前工作目录不同。这是两个不同的概念。 - Bryan Oakley
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接