Skip to content
Advertisement

Get Path of File Relative Path of File that Imported Module in Python

I have this code in my_program.py:

from my_module import do_stuff_with_file

do_stuff_with_file("hi.txt")

And this is my_module.py:

def do_stuff_with_file(fileName):
    print(fileName)
    # do stuff with the file

A file not found error arises when my_module.py is not in the same directory as my_program.py. This problem was solved using this code (my_module.py).

def do_stuff_with_file(fileName):
    fileName = os.path.join(os.path.dirname(sys.modules['__main__'].__file__), fileName)
    print(fileName)
    # do stuff with file

The issue arises when my_program.py is imported by a file in a different directory.

How can I fix this?

Advertisement

Answer

Given the following file hierarchy :

stack_overflow/
├─ q67993523/
   ├─ my_module/
   │  ├─ __init__.py
   ├─ 67993523.py
   ├─ hi.txt

With the following file content :

# 67993523.py
from my_module import do_stuff_with_file

do_stuff_with_file("hi.txt")
# my_module/__init__.py
def do_stuff_with_file(filename):
    print(f"{filename!s} content is :")
    with open(filename, "rt") as file:
        print(file.read())

and the file hi.txt :

Hello !

When I run C:pathtopython.exe C:/stack_overflow/q67993523/67993523.py (with the path to q67993523 included in my PYTHONPATH), with my current directory being q67993523/, I get :

hi.txt content is :
Hello !

But if I change my current dir to q67993523/my_module/ and execute the exact same command, I get :

hi.txt content is :
Traceback:
[...]
FileNotFoundError: [Errno 2] No such file or directory: 'hi.txt'

because relative to the current working directory q67993523/my_module/ there is no file hi.txt, the file would be ../hi.txt.

I think what you are doing is an instance of the XY problem.

What you are trying to achieve is to find a file given its name but not the location. It is very difficult to do, prone to error, and would include lots of hacks to work.
I don’t think it is actually what you want to do. What you want to do, I presume, is not to search for files but just to use them. So you should not lose the precious information of their location.

For example, in your main script (mine is 67993523.py), you know that the file is right there, in the same directory. But if you just send hi.txt, because the function don’t know the file location of the code that called her, it does not know where to search for the file.
Instead, give the complete file location, namely the absolute path.

If I change my main script to :

# 67993523.py
from pathlib import Path

from my_module import do_stuff_with_file

the_directory_of_this_pyfile = Path(__file__).parent
do_stuff_with_file((the_directory_of_this_pyfile / "hi.txt").absolute())

And run it with my current directory being q67993523/, I get :

C:stack_overflowq67993523hi.txt content is :
Hello !

And when I change my current directory to q67993523/my_module/, I get the same thing :

C:stack_overflowq67993523hi.txt content is :
Hello !

The difference is that in your script, the hi.txt filename assumes that your current working directory is q67993523/. If you have a different current working directory (because Pytest, because running the script for anywhere you want, … see the comment from @tdelaney) then there is no ./hi.txt file, so it will fail.

I encourage you to learn on the topic of current working directory and how to express the current Python file directory.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement