# Opening a file in Python

I use the following function for opening files in Python:

def file_path(relative_path):
folder = os.path.dirname(os.path.abspath(__file__))
path_parts = relative_path.split("/")
new_path = os.path.join(folder, *path_parts)
return new_path


I call it with a relative path, like this:

with open(file_path("my_files/zen_of_python.txt")) as f:


I like it because you can use a relative path works no matter where the Python script is executed from:

1. folder = os.path.dirname(os.path.abspath(__file__)) gets the absolute path to the folder holding the python script.
2. os.path.join(folder, *path_parts) gets an os-independent path to the file to open.

To further explain, let's say I have the following folder structure:

- parent_folder
- example.py
- my_files
- zen_of_python.txt


If example.py looks like this:

with open("my_files/zen_of_python.txt") as f:


Then I have to run example.py from the parent_folder directory or else it won't find my_files/zen_of_python.txt.

But if I open my_files/zen_of_python.txt using the file_path() function shown above, I can run example.py from anywhere.

One downside as @infinitezero pointed out is that you can't use an absolute path, but for my purposes, that's okay for my purposes. The script is self-contained. I'm not passing in external files when I run it.

Can anyone see any downside to this? Or does anyone have a more Pythonic way of accomplishing the same thing?

Your code represents a well-known pattern. In Java, files like this are called resource files and they are delivered together with the code in a .jar file (which is essentially a .zip file).

As pointed out in a comment, you cannot use your code with absolute paths. This is good since the entire purpose of the code is to find a resource relative to the source code that needs this resource.

The call to abspath looks redundant to me. I'm assuming that __file__ is already an absolute path. You may want to check the documentation about it.

A downside of your function is that you have to define it in each file that wants to open relative files since it uses __file__. You cannot import that function, as it is now.

• If you execute a script using a relative path (e.g., python my_file.py), then __file__ will be relative. You're right that a downside is that you cannot import the function unless it's in the same directory. You could fix this by accepting __file__ as a 2nd param. – Webucator Feb 5 '20 at 16:14

If using just os.path, this looks almost perfect.

• Move folder into the global scope, as there's no point not to. It means that the function can be made simpler - as it's now split into two seperate entities.
FOLDER = os.path.dirname(os.path.abspath(__file__))

def file_path(relative_path):
return os.path.join(folder, *relative_path.split("/"))


It would be better if you used pathlib. This is the modern version of os.path. If you do, then I would recomend just making folder as there would be no need for the function.

FOLDER = pathlib.Path(__file__).resolve().parent

with (FOLDER / 'my_files/zen_of_python.txt').open() as f:
...


Here are some examples of running it on Windows in Python 3.8.

>>> import pathlib
>>> FOLDER = pathlib.Path('foo')
>>> FOLDER / 'bar/baz'  # Unix style
WindowsPath('foo/bar/baz')
>>> FOLDER / 'bar\\baz'  # Windows style
WindowsPath('foo/bar/baz')
>>> FOLDER / 'bar' / 'baz'  # Pathlib style
WindowsPath('foo/bar/baz')