DEAR PEOPLE FROM THE FUTURE: Here's what we've figured out so far...

Welcome! This is a Q&A website for computer programmers and users alike, focused on helping fellow programmers and users. Read more

What are you stuck on? Ask a question and hopefully somebody will be able to help you out!
+1 vote

When I try to load a file, depending on where I execute the program from, I get a FileNotFoundError.

test.py

import json
import os

def load_json(file: str) -> dict:
    with open(file) as data:
        return json.load(data)


if __name__ == "__main__":
    file = os.path.join("data", "input.json")
    print(load_json(file))

If I execute it as python test.py it works but if I go to another folder and do python folder/test.py it doesn't work.

How can I solve this. I think it's caused by the relative path in file = os.path.join("data", "input.json")

I could write

path = pathlib.Path(__file__).parent.resolve()
file = os.path.join(path, "data", "input.json")

to get an absolute path instead, but I'm hoping there is a less verbose option.

Is there a way of making it work while still using the relative path?

by
edited by

1 Answer

+1 vote
 
Best answer

It really depends on what you want to achieve.

You could set a variable for the data folder, and reuse it as needed

from os.path import realpath, dirname
data_path = dirname(realpath(__file__)) + "/data"

with open(data_path + "/input.json") as data:
    ...

Or you could also change the script working directory

if __name__ == "__main__":
    os.chdir(dirname(realpath(__file__)))
    file = os.path.join("data", "input.json")
    print(load_json(file))

But it's a better idea to keep your scripts and data well separated. When launching the script then, you provide it with the path to the data folder either as an argument or eventually with an environment variable

import sys
if __name__ == "__main__":
    data_folder = sys.argv[1]
    file = os.path.join(data_folder, "input.json")
    print(load_json(file))

$ ./folder/test.py ./folder/data
by
selected by
Contributions licensed under CC0
...