views:

524

answers:

3

How do I reference a file relatively to a package's directory?

My directory structure is:

    /foo
     package1/
      resources/
      __init__.py
     package2/
      resources/
      __init__.py
     script.py

script.py imports packages package1 and package2. Although the packages can be imported by any other script on the system. How should I reference resources inside, say, package1 to ensure it would work in case os.path.curdir is arbitrary?

+2  A: 

If you want to reference files from the foo/package1/resources folder you would want to use the __file__ variable of the module. Inside foo/package1/__init__.py:

from os import path
resources_dir = path.join(path.dirname(__file__), 'resources')
Alex Morega
As noted by another answer, this won't work if your application is packaged in a zip file.
Glyph
A: 

This is a bad idea, because, if your package was installed as zipped egg, then resources can be unavailable.

If you use setuptool, don't forget to add zip_safe=False to the setup.py config.

Alexander Artemenko
This is true, but it should really have been in a comment rather than an answer, since it doesn't answer the question.
Glyph
A: 

You can be zip-safe and at the same time use a nice convenient API if you use twisted.python.modules.

For example, if I have a data.txt with some text in it and and this sample.py in one directory:

from twisted.python.modules import getModule
moduleDirectory = getModule(__name__).filePath.parent()
print repr(moduleDirectory.child("data.txt").open().read())

then importing sample will do this:

>>> import sample
'Hello, data!\n'
>>>

If your module is in a regular directory, getModule(__name__).filePath will be a FilePath; if it's in a zip file, it will be a ZipPath, which supports most, but not all, of the same APIs.

Glyph