我创建了一个名为“playr”的模块,它有一个 wav 文件的子目录:
user/repositories/python_packages/playr/
|
|--__init__.py
|--sounds/
| |--sound1.wav
| |--sound2.wav
| |--sound3.wav
在我的 __init__.py
中,有一个函数应该获取 sounds/
目录中所有文件的列表,以便播放选定的声音:
from os import listdir
import os.path
import subprocess
def play(sound=0):
wav_files = listdir('sounds')
sound_file = os.path.join('sounds', wav_files[sound])
return_code = subprocess.call(['afplay', sound_file])
因为我想共享此模块,我需要找到一种方法来获取 sounds/
目录的路径,而无需对绝对路径进行硬编码。父目录 user/repositories/python_packages/
包含在我的 PYTHONPATH
变量中。
目前,当我尝试在不同目录中使用 python env 中的模块时,它会像这样:
from playr import play
play()
----------------------------------------------------------------
FileNotFoundError: [Errno 2] No such file or directory: 'sounds'
我知道它没有找到 sounds/
目录,因为它在我当前的环境中查找,而不是在模块内查找。 我的问题是如何让我的函数在模块内而不是当前环境中查看。
到目前为止,我已经使用 os.path
和 pathlib
尝试了许多不同的方法。我还尝试了使用 module.__file__
任何帮助将不胜感激!
更新
我当前的解决方案是使用pathlib.Path(__file__)
最佳答案
编辑[2022-01-12]:
我使用 pathlib.Path(__file__)
使用更简单的解决方案更新了我的方法,它将完整的 PosixPath 返回到包目录中的文件,并且从那里可以轻松导航到所需的子目录。这要容易得多,不需要安装额外的软件包,并且对我来说 Python 3.6 - 3.10 工作得很好
我将以下内容放入__init__.py
import subprocess
from pathlib import Path
p = Path(__file__)
sounds_dir = p.parent / 'sounds'
def beep(sound=2):
sounds = [x for x in sounds_dir.iterdir()]
return_code = subprocess.call(['afplay', sounds[sound]])
为了使用,我确保将完成的包(重命名为 beepr
)添加到我的 PYTHONPATH 中,并且像这样使用它没有任何问题:
from beepr import beep
beep(2)
<小时/>
这是我使用过的(以前的)解决方案,需要 importlib.resources
并使用 Python 3.7 和 3.8,或向后移植 importlib_resources
与 <3.7
# py 3.7
import os, subprocess
from importlib.resources import path
def play(sound=0):
with path('playr', 'sounds') as sounds_path:
sounds = os.listdir(sounds_path)
audio_file = os.path.join(sounds_path, sounds[sound])
return_code = subprocess.call(['afplay', audio_file])
但是,除了不太简单之外,它也不适用于 Python 3.9 或 3.10
<小时/>关于python - 在Python中,如何获取模块内文件目录的路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56120179/