#/path2/bar.py
import os
print(os.getcwd())
print(__file__)
运行foo.py将给出输出:
/path1 # "import bar" causes the line "print(os.getcwd())" to run
/path2/bar.py # then "print(__file__)" runs
/path2/bar.py # then the import statement finishes and "print(bar.__file__)" runs
但是,如果你试图自己运行bar.py,你会得到:
/path2 # "print(os.getcwd())" still works fine
Traceback (most recent call last): # but __file__ doesn't exist if bar.py is running as main
File "/path2/bar.py", line 3, in <module>
print(__file__)
NameError: name '__file__' is not defined
希望这可以帮助 . 在测试其他解决方案时,这个警告花费了我很多时间和困惑呈现 .
1
import a_module
print a_module.__file__
实际上会给你加载的.pyc文件的路径,至少在Mac OS X上 . 所以我想你可以做到
import os
path = os.path.dirname(amodule.__file__)
import os,sys
if hasattr(sys,'frozen'): # only when running in py2exe this exists
base = sys.prefix
else: # otherwise this is a regular python script
base = os.path.dirname(os.path.realpath(__file__))
32
import os
path = os.path.abspath(__file__)
dir_path = os.path.dirname(path)
global modpath
modname = 'os' #This can be any module name on the fly
#Create a file called "modname.py"
f=open("modname.py","w")
f.write("import "+modname+"\n")
f.write("modpath = "+modname+"\n")
f.close()
#Call the file with execfile()
execfile('modname.py')
print modpath
<module 'os' from 'C:\Python27\lib\os.pyc'>
16 回答
我会尝试解决这个问题的一些变化:
找到被调用脚本的路径
查找当前正在执行的脚本的路径
查找被调用脚本的目录
(其中一些问题已在SO上提出,但已被重复关闭并重定向到这里 . )
使用__file__的注意事项
对于已导入的模块:
将返回模块的 absolute 路径 . 但是,给定下面的脚本foo.py:
用'python foo.py'调用它将只返回'foo.py' . 如果你添加一个shebang:
并使用./foo.py调用它,它将返回'./foo.py' . 从不同的目录调用它(例如将foo.py放在目录栏中),然后调用其中一个
或添加shebang并直接执行文件:
将返回'bar/foo.py'( relative 路径) .
查找目录
现在从那里去获取目录,
os.path.dirname(__file__)
也可能很棘手 . 至少在我的系统上,如果从与文件相同的目录中调用它,它将返回一个空字符串 . 恩 .将输出:
换句话说,它返回一个空字符串,所以如果你想将它用于当前的 file (而不是导入模块的 file ),这似乎不可靠 . 要解决这个问题,你可以将它包装在对abspath的调用中:
输出如下:
请注意,abspath()不解析符号链接 . 如果要执行此操作,请改用realpath() . 例如,使用以下内容创建指向file_import_testing.py的符号链接file_import_testing_link:
执行将打印绝对路径,如:
file_import_testing_link - > file_import_testing.py
使用检查
@SummerBreeze提到使用inspect模块 .
对于导入的模块,这似乎运行良好,并且非常简洁:
乖乖地回归绝对路径 . 但是,为了找到当前正在执行的脚本的路径,我没有看到使用它的方法 .
Source
如果使用
__file__
的唯一警告是当前相对目录为空(即,当从脚本所在的同一目录作为脚本运行时),那么一个简单的解决方案是:结果如下:
在
dirname()
调用之后,诀窍是or '.'
. 它将dir设置为.
,这意味着当前目录,并且是任何与路径相关的函数的有效目录 .因此,并不真正需要使用
abspath()
. 但是如果您仍然使用它,则不需要诀窍:abspath()
接受空白路径并将其正确解释为当前目录 .python中有
inspect
模块 .官方文件
例:
命令行实用程序
您可以将其调整为命令行实用程序,
创建
/usr/local/bin/python-which
让它可执行
如果您想知道脚本的绝对路径,可以使用Path对象:
cwd() method
resolve() method
你可以导入你的模块,然后点击它的名字,你就会得到它的完整路径
正如其他答案所说,最好的方法是使用
__file__
(下面再次演示) . 但是,有一个重要的警告,即如果您自己运行模块(即__main__
),则不存在__file__
.例如,假设您有两个文件(两个文件都在您的PYTHONPATH上):
和
运行foo.py将给出输出:
但是,如果你试图自己运行bar.py,你会得到:
希望这可以帮助 . 在测试其他解决方案时,这个警告花费了我很多时间和困惑呈现 .
实际上会给你加载的.pyc文件的路径,至少在Mac OS X上 . 所以我想你可以做到
你也可以试试
获取目录以查找更改 .
我想贡献一个常见的场景(在Python 3中)并探索一些方法 .
内置函数open()接受相对路径或绝对路径作为其第一个参数 . 相对路径被视为相对于当前工作目录,因此建议将绝对路径传递给该文件 .
简单地说,如果您使用以下代码运行脚本文件,则保证
example.txt
文件将在脚本文件所在的同一目录中创建:要修复此代码,我们需要获取脚本的路径并使其成为绝对路径 . 为了确保路径是绝对的,我们只需使用os.path.realpath()函数 . 要获取脚本的路径,有几个常用函数可返回各种路径结果:
os.getcwd()
os.path.realpath('example.txt')
sys.argv[0]
__file__
函数os.getcwd()和os.path.realpath()都基于当前工作目录返回路径结果 . 一般不是我们想要的 . sys.argv列表的第一个元素是根脚本(您运行的脚本)的路径,无论您是在根脚本本身还是在其任何模块中调用列表 . 在某些情况下它可能会派上用场 . file变量包含调用它的模块的路径 .
以下代码在脚本所在的同一目录中正确创建文件
example.txt
:这是微不足道的 .
每个模块都有一个
__file__
变量,显示了您现在所处位置的相对路径 .因此,获取模块的目录以通知它很简单:
所以我花了相当多的时间尝试用py2exe来做这个问题是获取脚本的基本文件夹,无论它是作为python脚本运行还是作为py2exe可执行文件运行 . 无论是从当前文件夹,另一个文件夹运行还是从系统路径运行(这是最难的),它都可以运行 .
最后我使用了这种方法,使用sys.frozen作为在py2exe中运行的指示器:
从python包的模块内部,我不得不引用一个与package在同一目录中的文件 . 防爆 .
所以在上面我不得不从my_lib_a.py模块调用maincli.py,知道top_package和maincli.py在同一个目录中 . 这是我如何获得maincli.py的路径:
基于PlasmaBinturong的发布,我修改了代码 .
如果您希望在"program"中动态执行此操作,请尝试以下代码:
我的观点是,你可能不知道模块的确切名称"hardcode"它 . 它可以从列表中选择,也可能当前没有运行以使用__file__ .
(我知道,它在Python 3中不起作用)
我试图摆脱“全局”问题,但发现它不起作用的情况我认为“execfile()”可以在Python 3中模拟因为这是在一个程序中,它可以很容易地放在方法或模块中重用 .
我不明白为什么没有人在谈论这个,但对我来说最简单的解决方案是使用 imp.find_module("modulename") (文档here):
它给出了一个元组,其路径位于第二位:
这种方法优于“检查”方法的优点是您不需要导入模块使其工作,您可以在输入中使用字符串 . 例如,检查在另一个脚本中调用的模块时很有用 .
EDIT :
在python3中,
importlib
模块应该:importlib.util.find_spec
的文件: