如何确保 python 找到必要的数据文件?

How can I make sure that python finds the necessary data files?

请考虑这个脚本:

$ tree my_application 
my_application
├── my_application
│   ├── sound.mp3
│   ├── __init__.py
│   ├── my_application.py
│   ├── my_application.pyc
│   └── __pycache__
│       ├── __init__.cpython-34.pyc
│       └── my_application.cpython-34.pyc
├── my_application.egg-info
│   ├── dependency_links.txt
│   ├── entry_points.txt
│   ├── PKG-INFO
│   ├── requires.txt
│   ├── SOURCES.txt
│   └── top_level.txt
├── run.py
├── MANIFEST.in
└── setup.py

my_application.py 是一个使用 mplayer:

播放 sound.mp3 的脚本
class Sound():
    def __init__(self):
        self.cmd = ["mplayer", "sound.mp3"]            
    def play(self):
        subprocess.Popen(self.cmd)

setup.py 是您的经典 setup.py 文件,具有 console_scriptmy_application:main.

MANIFEST.in 包含对 sound.mp3 的引用以确保它在 运行ning setup.py:

时被复制
include my_application/sound.mp3
global-exclude *.pyc

run.py 包含 运行 my_applicationmain() 函数的一小段代码:

from my_application import main

if __name__ == "__main__":
    main()

还有一个 __init__.py 文件,因此 main() 函数可以正确显示给 'outside world':

from .my_application import main

__all__ = ["main"]

现在,当我在内部 my_application 目录中 运行 main() 函数时,此脚本有效。但是只要函数是来自其他地方的 运行 ,例如通过 运行ning run.py 或使用控制台脚本,mplayer 抱怨找不到 sound.mp3:

Cannot open file 'sound.mp3': No such file or directory

如何确保 mplayer 找到 sound.mp3,无论我在哪个目录?

如果您使用的是安装工具,您可以使用pkg_resources来检索文件的正确路径:

import pkg_resources

class Sound():
    def __init__(self):
        sound_path = pkg_resources.resource_filename(
            'my_application', 'sound.mp3')
        self.cmd = ['mplayer', sound_path]

    ...