我们正在使用部署在Windows和Linux上的代码存储库-有时在不同的目录中。项目中的一个模块应该如何引用项目中的一个非python资源(CSV文件等)?

如果我们这样做:

thefile = open('test.csv')

or:

thefile = open('../somedirectory/test.csv')

只有当脚本从一个特定目录或目录的一个子集运行时,它才会工作。

我想做的是:

path = getBasePathOfProject() + '/somedirectory/test.csv'
thefile = open(path)

这可能吗?


当前回答

在Python中,路径是相对于当前工作目录的,在大多数情况下,当前工作目录就是运行程序的目录。当前工作目录很可能与模块文件的目录不相同,因此使用相对于当前模块文件的路径总是一个糟糕的选择。

使用绝对路径应该是最好的解决方案:

import os
package_dir = os.path.dirname(os.path.abspath(__file__))
thefile = os.path.join(package_dir,'test.cvs')

其他回答

尝试使用相对于当前文件路径的文件名。'./my_file'示例:

fn = os.path.join(os.path.dirname(__file__), 'my_file')

在Python 3.4+中,你也可以使用pathlib:

fn = pathlib.Path(__file__).parent / 'my_file'

我经常使用类似的方法:

import os
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), 'datadir'))

# if you have more paths to set, you might want to shorten this as
here = lambda x: os.path.abspath(os.path.join(os.path.dirname(__file__), x))
DATA_DIR = here('datadir') 

pathjoin = os.path.join
# ...
# later in script
for fn in os.listdir(DATA_DIR):
    f = open(pathjoin(DATA_DIR, fn))
    # ...

的变量

__file__

保存编写该代码的脚本的文件名,因此可以使路径相对于脚本,但仍然使用绝对路径编写。它运行得非常好,原因如下:

路径是绝对的,但仍然是相对的 项目仍然可以部署在相对容器中

但是你需要注意平台兼容性——Windows操作系统。pathsep与UNIX不同。

如果您正在使用安装工具或分发(setup.py安装),那么访问这些打包资源的“正确”方式似乎是使用package_resources。

对你来说,这个例子就是

import pkg_resources
my_data = pkg_resources.resource_string(__name__, "foo.dat")

当然,是哪个读取了资源,读取的二进制数据是my_data的值

如果你只是需要文件名,你也可以使用

resource_filename(package_or_requirement, resource_name)

例子:

resource_filename("MyPackage","foo.dat")

这样做的好处是,即使它是一个像鸡蛋一样的存档发行版,它也能保证工作。

看到http://packages.python.org/distribute/pkg_resources.html resourcemanager-api

你可以使用build in __file__变量。它包含当前文件的路径。我将在项目根的一个模块中实现getBaseOfProject。在那里,我将获得__file__的路径部分,并将返回它。然后可以在项目中的任何地方使用此方法。

如果你想稍后将脚本编译为.exe,那么__file__不会给你.exe文件的路径。在这种情况下你应该这样做

使用sys.argv [0]

sys。Argv[0]给出了文件的路径,当它是一个。exe文件,当你运行脚本,如python script.py

这就是我目前引用事物的方式

os.path.join (os.path.dirname (os.path.abspath (sys.argv[0])),“资源”)

这里有更详细的解释