0

I have a Python project with subdirectories and I'm unable to import a module located in the root directory, here logger.py, from another module in a subdirectory, here composite.py.

The problem is that logger.py point to a log file in the log directory with a relative path name to it, so composite.py can't find this file from it's sub directory.

How can I import module logger from composite.py and from another module in the root directory, like module.py ?

├── data/
    module.py
    logger.py
    ├── composite/
    │   ├── composite.py
    ├── log/
    │   ├── info.log

This work :

data/logger.py:

h_info =      RotatingFileHandler('log/info.log', [...])

data/module.py:

import logger

This doesn't work:

data/composite/composite.py:

from data import logger

FileNotFoundError: [Errno 2] No such file or directory: '/home/abc/project/python/xyz/data/composite/log/info.log'
Florent
  • 1,791
  • 22
  • 40

1 Answers1

3

It doesn't work because your code is relying on the current directory to open the log file.

Since you know the relative path to your log file from the file you're opening the log, you can use os.path.dirname(__file__) to locate the current directory module then join the rest:

in logger.py, os.path.dirname(__file__) is '/home/abc/project/python/xyz/data'. Just add the log folder part.

h_info = RotatingFileHandler(os.path.join(os.path.dirname(__file__),'log/info.log'), [...])

or in a more portable way:

h_info = RotatingFileHandler(os.path.join(os.path.dirname(__file__),"log","info.log"), [...])

NEVER reference resource/external files with a relative path. Always use either absolute path from a config file or use this technique to be sure of the starting directory. Never use os.chdir either to do this.

Similar issue: Weird python file path behavior path-behavior

Interesting related read: os.getcwd() vs os.path.abspath(os.path.dirname(__file__))

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • Thank you, it works very well but I need to join `log/info.log` instead of `../log/info.log` to the module path, like in `os.path.join(os.path.dirname(__file__), 'log/info.log')` – Florent Aug 18 '18 at 10:29
  • Well, I learned something new here too. I usually use `os.getcwd()`. Here's a brief on which is better to be used. [os.getcwd() vs os.path.abspath(os.path.dirname(__file__))](https://stackoverflow.com/questions/11274040/os-getcwd-vs-os-path-abspathos-path-dirname-file) – Tom Wojcik Aug 18 '18 at 11:20