15

I have a directory structure like this...

dir/
  build.py
dir2
  dir3/
  packages.py

Now the build.py needs packages.py -- and note that dir2 is not a package.

So what's the best way to get packages.py loaded into build.py (the directory structure can't be changed)

EDIT

The sys.path.append solution seems good -- but there is one thing -- I need to use the packages.py file rarely -- and keeping a sys.path that includes a directory that is used rarely, but is at the front -- is that the best thing?

EDIT II

I think the imp solution is best.

import imp    
packages = imp.load_source('packages', '/path/to/packages.py')

EDIT III

for Python 3.x

Note that imp.load_source and some other function have been deprecated. So you should use the imp.load_module today.

fp, pathname, description = imp.find_module('packages', '/path/to/packages.py')
try:
    mod = imp.load_module('packages', fp, pathname, description)
finally:
    # since we may exit via an exception, close fp explicitly
    if fp:
        fp.close()
treecoder
  • 43,129
  • 22
  • 67
  • 91
  • 1
    The best option here is to make it a package. Can you **really** not do that? – Gareth Latty May 10 '12 at 12:14
  • NO I can't. Because inside `dir2`, other than `packages.py` -- all others are non-python files. The `packages.py` just contains some config info for the `build.py` – treecoder May 10 '12 at 12:17
  • Have you considered using a different format for the configuration file? If your configuration doesn't require code in it, why not store the configuration as `JSON` or some other similar format? That way you don't need to import it. Also, you can have other files in a Python package, I don't really see why that is an issue. – Gareth Latty May 10 '12 at 12:19
  • About other formats -- I think in my case python file for config is more suitable and flexible than anything else. – treecoder May 10 '12 at 12:43
  • 1
    @good_computer, find_module and load_module is deprecated too and so will the whole imp module in the future, maybe you should replace it with an example using importlib if possible – freeforall tousez Aug 26 '14 at 21:32

2 Answers2

10

You could do:

sys.path.append('./dir2/dir3')
import packages

Or better yet:

sys.path.append(os.path.join(os.path.dirname(__file__), 'dir2/dir3'))
import packages

Or (taken from here: How to import a module given the full path?)

import imp    
packages = imp.load_source('packages', '/path/to/packages.py')
Community
  • 1
  • 1
Daren Thomas
  • 67,947
  • 40
  • 154
  • 200
6

Would the 'one right way' to do be the third ? - avoids messing directly with sys.path

I meet the same problems, and I solve it.

dir/
  build.py
dir2
  dir3/
    packages.py
  1. add the file __init__.py into the dir1, dir2, dir3 ...
  2. Inside a package hierarchy, use two dots.

bulid.py want to import packages.py, write in bulid.py:

import ..dir2.dir3.packages
from ..dir2.dir3.packages import function

https://docs.python.org/2/whatsnew/2.5.html#pep-328-absolute-and-relative-imports

Importing modules from parent folder

How to import a Python class that is in a directory above?

1943 Yonv
  • 300
  • 3
  • 11