0

I would like to keep a resource file (which is really anything shared among scripts but not Python itself) in my PYTHONPATH so that it can be used by modules that are in that path, which are in turn invoked by different end scripts/apps.

PYTHONPATH
  |
  |--Module1.py
  |--Module2.py
  |--Resource.res

Is there a way I can easily reference a resource (Resource.res) file that is located under the PYTHONPATH hierarchy along with actual Python modules that are shared, without supplying the full path to the file? There is equivalent way of getting a resource file from Java's classpath, which is where I'm getting the idea.

The contents of the resource file should be irrelevant but just for illustration's sake, it could be anything non-pythonic, such as random data, config, etc.

3 Answers 3

1

It's trivial to write a function that does this:

import sys, os.path

def resolve(filename):
    for directory in sys.path:
        path = os.path.join(directory, filename)
        if os.path.isfile(path):
            return path

This version returns None if the file can't be found on the path. You could also raise an exception.

Sign up to request clarification or add additional context in comments.

3 Comments

OP asked specifically to use PYTHONPATH which is not the same as sys,path. It is available by os.getenv('PYTHONPATH'), so if he replaces your sys,path with that function call it should work.
This doesn't work if the package containing the resource is loaded from a zip file.
@Paul: Not quite, since sys.path is a list and os.getenv('PYTHONPATH') returns a string.
1

This is very similar to @kindall's answer, but uses the PYTHONPATH environment variable instead of sys.path to determine the directory search list:

import os
import sys

def resource_file_path(filename):
    """ Search for filename in the list of directories specified in the
        PYTHONPATH environment variable.
    """
    pythonpath = os.environ.get("PYTHONPATH")
    if pythonpath:
        for d in pythonpath.split(os.pathsep):
            filepath = os.path.join(d, filename)
            if os.path.isfile(filepath):
                return filepath
    return None

Comments

0

You can read arbitrary files from a package using pkgutil.get_data https://docs.python.org/3/library/pkgutil.html#pkgutil.get_data

For instance, to load a GIF icon from your package:

image = pkgutil.get_data(__name__, "icon.gif")

You can vary the package argument to load things from different places. If you're okay of installing a recent setuptools you could use their version of it, which provides a few more possibilities http://setuptools.readthedocs.io/en/latest/pkg_resources.html#basic-resource-access

These work regardless on how the package is installed (separate files on the filesystem, or as a zip/egg/whatever.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.