0

Here is the folder structure of my code:

project/
    latplan/
         __init__.py
         model.py
    samples/
         text.txt
    main2.py
lyrics/
    main.py

Content of each file:

main.py

#!/usr/bin/env python
import sys
sys.path.append(r"../project")
import latplan

... = some other code where latplan module was needed, then:

latplan.model.NN().load()

main2.py

#!/usr/bin/env python
import latplan

latplan.model.NN().load()

model.py

class NN():
    x = 5
    def load(self):
        with open("samples/text.txt", "r") as f:
            print("success")

When I execute main2.py (from project/ folder):

./main2.py

I get :

success

But when I execute main.py (from lyrics/ folder):

./main.py

I get the error:

"\lyrics../project\latplan\model.py", line 6, in load with open("samples/text.txt", "r") as f: FileNotFoundError: [Errno 2] No such file or directory: 'samples/text.txt

I can only modify main.py file, so how can I do so, in order to avoid this error ?

Thanks a lot

RandomFellow
  • 317
  • 1
  • 9
  • 1
    A relative path is always relative to the current working directory... If you are in `lyrics/` then `samples/text.txt` is not correct. You need `../samples/text.txt`... – Tomerikoo Jul 21 '22 at 15:07

1 Answers1

1

If you can only modify main.py, the only workable approach is to change the working directory on launch. After modifying sys.path, you can add :

os.chdir('../project')

which will change your working directory for when it looks up new relative path names outside of import contexts (it will also affect import contexts, but only when the empty string is in sys.path, which by default only happens when run interactively, or when the script is read from stdin, neither of which are the expected case here).

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Ok, but actually in the "lyrics" directory there are other files and subfolders (that I did not show to keep things simple), so I m afraid your method will prevent me to call pieces of code from "lyrics" (when executing main.py). Or maybe I can change directory just for **latplan.model.NN().load()** and then go back to "lyrics" directory ? – RandomFellow Jul 21 '22 at 15:10
  • 1
    @RandomFellow: Yeah, but that's really brittle. Correctly written library code should not be using relative paths (implicitly tied to the working directory) at all. Instead, if there are data files shipped alongside them, in a properly installable package [you'd use `package_data` and `pkg_resources`](https://stackoverflow.com/q/47817944/364696), or in a more ad-hoc system, you'd construct the paths relative to the module file by using the `__file__` constant as a base (e.g. to open a file in the same directory as the module, `pathlib.Path(__file__).with_name('resource.txt')` or the like). – ShadowRanger Jul 21 '22 at 15:14
  • [Example for using `__file__` here](https://stackoverflow.com/a/72103275/364696) – ShadowRanger Jul 21 '22 at 15:18