简体   繁体   中英

In Python, how do I get the path to a directory of files located within a module

I created a module called 'playr' that has a subdirectory of wav files:

user/repositories/python_packages/playr/
|
|--__init__.py
|--sounds/
|   |--sound1.wav
|   |--sound2.wav
|   |--sound3.wav

In my __init__.py is a function that should get a list of all the files in the sounds/ directory in order to play a selected sound:

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])

Because I'd like to share this module, I need to find a way to get the path to the sounds/ directory without hardcoding the absolute path . The parent directory user/repositories/python_packages/ is included in my PYTHONPATH variable.

Currently, when I attempt to use the module from a python env in a different directory, it goes like this:

from playr import play

play()


----------------------------------------------------------------
FileNotFoundError: [Errno 2] No such file or directory: 'sounds'

I understand it's not finding the sounds/ directory because it's looking in my current environment and not within the module. My question is how can I get my function to look within the module instead of the current environment .

So far I've tried many different methods using os.path and pathlib . I've also attempted different ways of using module.__file__

Any help would be greatly appreciated!

The solution in python 3.7+ is importlib.resources , or the backport importlib_resources for < 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])

os.path.abspath(__file__) returns the full pathname to the current module file, ie something like /foo/bar/baz/module.py .

os.path.dirname(fullpath) chops off the filename and just returns the directory, ie /foo/bar/baz .

So, you want:

os.path.join(os.path.dirname(os.path.abspath(__file__)), 'sounds')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM