Open file in a relative location in Python
Solution 1
With this type of thing you need to be careful what your actual working directory is. For example, you may not run the script from the directory the file is in. In this case, you can't just use a relative path by itself.
If you are sure the file you want is in a subdirectory beneath where the script is actually located, you can use __file__
to help you out here. __file__
is the full path to where the script you are running is located.
So you can fiddle with something like this:
import os
script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)
Solution 2
This code works fine:
import os
def readFile(filename):
filehandle = open(filename)
print filehandle.read()
filehandle.close()
fileDir = os.path.dirname(os.path.realpath('__file__'))
print fileDir
#For accessing the file in the same folder
filename = "same.txt"
readFile(filename)
#For accessing the file in a folder contained in the current folder
filename = os.path.join(fileDir, 'Folder1.1/same.txt')
readFile(filename)
#For accessing the file in the parent folder of the current folder
filename = os.path.join(fileDir, '../same.txt')
readFile(filename)
#For accessing the file inside a sibling folder.
filename = os.path.join(fileDir, '../Folder2/same.txt')
filename = os.path.abspath(os.path.realpath(filename))
print filename
readFile(filename)
Solution 3
I created an account just so I could clarify a discrepancy I think I found in Russ's original response.
For reference, his original answer was:
import os
script_dir = os.path.dirname(__file__)
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)
This is a great answer because it is trying to dynamically creates an absolute system path to the desired file.
Cory Mawhorter noticed that __file__
is a relative path (it is as well on my system) and suggested using os.path.abspath(__file__)
. os.path.abspath
, however, returns the absolute path of your current script (i.e. /path/to/dir/foobar.py
)
To use this method (and how I eventually got it working) you have to remove the script name from the end of the path:
import os
script_path = os.path.abspath(__file__) # i.e. /path/to/dir/foobar.py
script_dir = os.path.split(script_path)[0] #i.e. /path/to/dir/
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)
The resulting abs_file_path (in this example) becomes: /path/to/dir/2091/data.txt
Solution 4
It depends on what operating system you're using. If you want a solution that is compatible with both Windows and *nix something like:
from os import path
file_path = path.relpath("2091/data.txt")
with open(file_path) as f:
<do stuff>
should work fine.
The path
module is able to format a path for whatever operating system it's running on. Also, python handles relative paths just fine, so long as you have correct permissions.
Edit:
As mentioned by kindall in the comments, python can convert between unix-style and windows-style paths anyway, so even simpler code will work:
with open("2091/data/txt") as f:
<do stuff>
That being said, the path
module still has some useful functions.
Solution 5
I spend a lot time to discover why my code could not find my file running Python 3 on the Windows system. So I added . before / and everything worked fine:
import os
script_dir = os.path.dirname(__file__)
file_path = os.path.join(script_dir, './output03.txt')
print(file_path)
fptr = open(file_path, 'w')
Related videos on Youtube
![Neuron](https://lh5.googleusercontent.com/-HcKtiretO2g/AAAAAAAAAAI/AAAAAAAAAH0/IXGAL7MX8sQ/photo.jpg?sz=256)
Neuron
We're made of star stuff. We are a way for the cosmos to know itself. he/him
Updated on February 16, 2022Comments
-
Neuron over 2 years
Suppose my python code is executed a directory called
main
and the application needs to accessmain/2091/data.txt
.how should I use
open(location)
? what should the parameterlocation
be?I found that below simple code will work.. does it have any disadvantages?
file = "\2091\sample.txt" path = os.getcwd()+file fp = open(path, 'r+');
-
orip almost 13 yearsYou're using unescaped backslashes. That's one disadvantage.
-
Russ almost 13 yearsSeveral disadvantages. 1) As per @orip, use forward slashes for paths, even on windows. Your string won't work. Or use raw strings like
r"\2091\sample.txt"
. Or escape them like"\\2091\\sample.txt"
(but that is annoying). Also, 2) you are using getcwd() which is the path you were in when you execute the script. I thought you wanted relative to the script location (but now am wondering). And 3), always useos.path
functions for manipulating paths. Your path joining line should beos.path.join(os.getcwd(), file)
4) the ; is pointless -
Russ almost 13 yearsAnd for good measure... 5) use context guards to keep it clean and avoid forgetting to close your file:
with open(path, 'r+') as fp:
. See here for the best explanation ofwith
statements I've seen. -
OPMendeavor over 4 yearsbeside the necessary care on slashes, as just indicated, there is the function
os.path.abspath
to get easly the full path of the relative path to open. final statement looks like this:os.path.abspath('./2091/sample.txt')
-
-
kindall almost 13 years
relpath()
converts a pathname to a relative path. Since it's already a relative path, it will do nothing. -
Wilduck almost 13 yearsIt will convert it from a unix-style path to windows-style path if appropriate. Is there another function in the
os.path
module that would be a better choice? -
kindall almost 13 yearsWindows will already work fine with a UNIX-style path. At least the NT-based series will (2000, XP, Vista, 7). No conversion is necessary.
-
Russ almost 13 yearsNot true... the working directory inside a script is the location you ran the script from, not the location of the script. If you run the script from elsewhere (maybe the script is in your system path) the relative path to the subdirectory will not work. Please see my answer on how to get around this.
-
Russ almost 13 yearsThis answer is not quite correct and will cause problems. Relative paths are by default relative to the current working directory (path the script was executed from), and NOT the actual script location. You need to use
__file__
. Please see my answer. -
Admin almost 13 yearsI found that below simple code will work..does it have any disadvantages ? <pre> file="\sample.txt" path=os.getcwd()+str(loc)+file fp=open(path,'r+');<code>
-
orip almost 13 years@Russ - the OP's example uses
getcwd()
. I read the original description as "relative to where I run the script, regardless of where the code sits". -
Russ almost 13 years@orip - the OP added the getcwd() call 3 hrs after the question. No matter... moving on. :)
-
Cory Mawhorter almost 11 years@Arash The disadvantage to that is the cwd (current working directory) can be anything, and won't necessarily be where your script is located.
-
Cory Mawhorter almost 11 years
__file__
is a relative path (at least on my setup, for some reason), and you need to callos.path.abspath(__file__)
first. osx/homebrew 2.7 -
Luke Taylor over 8 yearsYou could even combine both approaches for the simpler
os.path.dirname(os.path.abspath(__file__))
-
Grant Hulegaard over 8 years@LukeTaylor Indeed that would be better than trying to replicate the
os.path.dirname
functionality yourself as I did in my answer last year. -
foobarbecue about 8 yearsDid the author of this answer confuse os.path.relpath with os.path.abspath?
-
Soumendra almost 8 yearsos.path.dirname(file) is not working for me in Python 2.7. It is showing
NameError: name '__file__' is not defined
-
Enkum over 5 years@Soumendra I think you are trying it in the console. Try it in a *.py file.
-
M. Paul over 5 yearsFor me accessing the file in the parent folder of the current folder did not worked..the .. is added as string..
-
Mr_and_Mrs_D about 5 yearsInstead of
path = "/".join(script_directory) + "/" + rel_path
you should use the os module as inpath = os.path.join(script_directory, rel_path)
. Instead of manually parsing the path you should be usingscript_path = os.path.dirname(__file__)
-
Mr_and_Mrs_D about 5 yearsBetter:
file_path = os.path.join(script_dir, 'output03.txt')
-
Ângelo Polotto about 5 yearsI tried on Windows OS that but I didn't have success.
-
Mr_and_Mrs_D about 5 yearsInteresting - can you print script_dir? Then turn it to absolute path as in
script_dir = os.path.abspath(os.path.dirname(__file__))
-
Ângelo Polotto about 5 yearsI will try that, if I succeed, I will change the answer.
-
lonstar almost 5 yearsDid not work on Windows. Path to file is correct but Python states "file not found" and shows the path with \\ separators.
-
Ronald about 4 yearsBackslashes are escape characters for several characters. If you happen to encounter
\t
like for example\top\directory
, than '\t' is interpreted as a tab-character and your 'trick' fails. The best option is to use the raw string formatr'C:\Users\chidu\Desktop\Skipper New\Special_Note.txt'
which does not try to 'escape' characters. -
pchtsp over 3 yearsin Ubuntu and python3, I had to take the quotes from
'__file__'
so it became:fileDir = os.path.dirname(os.path.realpath(__file__))
-
Neuron over 2 yearsplease use
with data_folder.open() as f
instead -
Neuron over 2 yearsall upper case names should be reserved for constants
-
James Wong over 2 yearsIn this case, wouldn't BASE_DIR be a constant? The parent folder of the script being run won't change during runtime.
-
FLAW over 2 yearsshouldn't you use
os.path.join
for2091/data.txt
? woudn't it cause problems in window?\` &
/` -
Mauricio Gracia Gutierrez over 2 yearsto avoid using / or \ you can
os.path.join(path,'folderA','file.txt')