1

I have a directory structure that looks like this:

foo/
   __init__.py
   db.py
   database.db
main.py

Now, in db.py, I read the contents of the database:

open('database.db').read()

This works as long as I am running db.py directly. However, when I try to import the foo package in main, and then run db.py, it fails with a file not found error.

How can I avoid this? (Preferably without making any changes to the modules in the foo package)

(Note: I am aware of a solution like this Relative paths in Python but that would entail a lot of modifications to my foo package)

EDIT 1: Is it not possible to add something to __init__.py so that python can find my files?

EDIT 2: As another small example, consider what happens when I start to have nested packages:

foo/
  baz/
    __init__.py
    mod.py
    modules.json
  __init__.py
  db.py
  database.py
main.py

Now, if main.py uses the foo package, and db.py requires the baz package, then I need to start making more complicated changes in the modules of the baz as well as the foo package, so that the file reads succeed.

This kind of a situation is happening when I need to use a git module that has several nested submodules. Obviously, it's not very convenient to make so many changes.

3
  • What modification to foo package would stackoverflow.com/questions/918154/relative-paths-in-python entail? As I see it, it would only entail changes to db.py . Commented Aug 5, 2015 at 10:16
  • @AnandSKumar this is obviously a small example, but there are a lot of references like this. Is it not possible to add something to __init__.py so that python can find my files? Commented Aug 5, 2015 at 10:18
  • in python3 i like from pathlib import Path; HERE = Path(__file__).parent. you could define that in your __init__ and then use things like DATA_PATH = HERE / '../data/test.csv'. Commented Aug 5, 2015 at 10:47

2 Answers 2

1

One solution can be to mask the open() function with a function of your own, in db.py , and in that custom open() function, you can open the file after appending the directory of __file__ . Example -

def open(file,mode='r',buffering=-1):
    import __builtin__    #use import builtins for Python 3.x
    import os.path
    filePath = os.path.join(os.path.dirname(__file__),file)
    return __builtin__.open(filePath,mode,buffering)

__builtin__.open() (or for Python 3.x - builtins.open() ) points to the built-in open() function.

I have used buffering =-1 as it seems to be the default according to documentation , you can leave out that argument altogether, if its not needed.

If possible, you should not mask (maybe use a different name like - open_file() ) , but seems like you do not want to do that.

Though I still think masking should be done only when there is no other solution. Also, please note you should not be import db.py as from db import * , that may cause similar masking of open() in the other .py file where its imported (Ideally, it is not recommended to do from <module> import * in any situtation) .

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

4 Comments

Please have a look at my updated question, to see how problematic this is becoming :/
With this solution you just need to add the above function as the first function in all py files, thats it, no other changes.
The only other way i can think of is to change directory to that module, but that would not work, because __init__.py is only run when the module is imported first time, not always when modules are imported.
Hmm, this seems to be the only solution then. Ok. Thanks.
0

Use of this module will to resolve this import error issue, the error that you mentioned is issue about path. so the error was python interpreter coulnt find the path where your modules has specified. if you use this module it would work fine.

 sys.path 

A list of strings that specifies the search path for modules. Initialized from the environment variable PYTHONPATH, plus an installation-dependent default

import sys
sys.path.append('..\Desktop\New folder')# folder destination
from foo import db

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.