I would like to find the relative path between two directories on my system.
Example:
If I have pathA == <pathA> and pathB == <pathA>/dir1/dir2, the relative path between them will be dir1/dir2.
How could I find it in python? Is there a tool I could use?
If pathB is contained in pathA, I could just do pathB.replace(pathA, '') to get this relative path, but what if pathB isn't contained in pathA?
os.path.relpath(path1, path2) # that's it
Just use the relpath() function of the os module.
import os
os.path.relpath(pathA, pathB)
As per the docs,
os.path.relpath(path[, start])
Return a relative filepath to path either from the current directory
or from an optional start directory. This is a path computation: the
filesystem is not accessed to confirm the existence or nature of path
or start.
Related
I've found two ways of listing files from a specified directory from other posts here on Stack Overflow but I can't seem to get them working. The first one returns the path and second return the files I'm looking for but also the path. I have tried several ways like renaming the target directory and files but it doesn't seem to do the trick.
The code in question:
import glob
jpgFilenamesList = glob.glob(r"C:\Users\viodo\PycharmProjects\pythonProject")
print(jpgFilenamesList)
mydir = r"C:\Users\viodo\PycharmProjects\pythonProject"
file_list = glob.glob(mydir + "/*.jpg")
print(file_list)
what I get:
['C:\\Users\\viodo\\PycharmProjects\\pythonProject']
['C:\\Users\\viodo\\PycharmProjects\\pythonProject\\dngjknfjkg.jpg', 'C:\\Users\\viodo\\PycharmProjects\\pythonProject\\fjkdnfkl.jpg', 'C:\\Users\\viodo\\PycharmProjects\\pythonProject\\skdklenfkd.jpg']
Solution found in another thread: Python glob multiple filetypes
Some tweaking got it running smoth. Thanks for the help!
Glob returns a list of pathnames relative to the root directory. That root directory is assumed to be your current working directory unless the glob pattern specified is an absolute path. In short, because your pattern is an absolute path pattern, the returned files will not be relative, but absolute, including the entire path.
When not using an absolute path pattern, in some cases, you could get just a file name if a file name matches in the current working directory. That file name would of course be relative to the current working directory.
In Python 3.10, you should be able to change the assumed root directory without using an absolute pattern via a new root_dir parameter, but this is not currently available in 3.9 and below: https://docs.python.org/3.10/library/glob.html.
In your case, as mentioned in the comments by othes, os.path.basename should be able to get just the file name if that is what you are after. Alternatively, you could change the current working directory via os.chdir and provide a glob pattern of simply *.jpg and get just the file names relative to the that current working directory, both are reasonable solutions.
Extracting the base name:
mydir = r"C:\Users\viodo\PycharmProjects\pythonProject"
file_list = [os.path.basename(f) for f in glob.glob(mydir + "/*.jpg")]
or returning the files relative to an arbitrary "current working directory":
os.chdir(r"C:\Users\viodo\PycharmProjects\pythonProject")
file_list = glob.glob("*.jpg")
Depending on your requirements, one solution may be better than the other.
I'm currently facing the problem that I'm working with different files. Within some of those files are other files - absolute files - I do not want to change them all to relative path since then I'll run into another problem. So my question is whether I can indicate a relative path within a function with e.g. adding two dots. So this is the code snipped:
if not all(np.array(skills_dict['snames']) == df_cube['img_path'].values)
So 'img_path' is the absolute path and I would like to make it relative for this function, something quirky like
df_cube['..'+'img_path'].values
Maybe someone could help me with that. Highly appreciated! Thanks!
you can do something like this. It will return the relative path of absolute_path. You can replace that with whatever absolute path you need to.
import os
def get_rel_path(absolute_path):
"""
Gets the relative path of absolute_path
"""
return os.path.dirname(absolute_path)
I am trying to get the absolute path of a file, but it's not working. My Code is only showing the path to the directory of my running code. This are the two way I have tried:
1)
import os
print(os.path.abspath("More_Types.py"))
2)
import os
print(os.path.realpath("More_Types.py"))
But I continue to get the full path to my running program. How can I get the correct path to file, that is located some where else in my Computer?
PS: I am sorry I can't provide the output because it will reveal all the folders to my running program.
More_Types.py, subdir/More_Types.py and ../More_Types.py are relative paths.
Outcome
If you provide a relative path, realpath and abspath will return an absolute path relative to the current working directory. So essentially, they behave like os.path.join with the current working directory as first argument:
>>> import os.path
>>> os.path.join(os.getcwd(), 'More_Types.py') == os.path.abspath('More_Types.py')
True
This explains, why you get the result you explained.
Explanation
The purpose of abspath is to convert a relative path into an absolute path:
>>> os.path.abspath('More_Types.py')
'/home/meisterluk/More_Types.py'
Unlike abspath, relpath also follows symbolic links. Technically, this is dangerous and can get you caught up in infinite loops (if a link points to any of its parent directories):
>>> os.path.abspath('More_Types.py')
'/net/disk-user/m/meisterluk/More_Types.py'
Proposed solution
However, if you want to retrieve the absolute path relative to some other directory, you can use os.path.join directly:
>>> directory = '/home/foo'
>>> os.path.join(directory, 'More_Types.py')
'/home/foo/More_Types.py'
>>>
I think the best answer to your question is: You need to specify the directory the file is in. Then you can use os.path.join to create an absolute filepath.
You could use this if you want:
import os
a='MoreTypes.py'
for root , dirs , files in os.walk('.') :
for file in files:
if file==a:
print(os.path.join(root,file))
For reference. The absolute path is the full path to some place on your computer. The relative path is the path to some file with respect to your current working directory (PWD). For example:
Absolute path:
C:/users/admin/docs/stuff.txt
If my PWD is C:/users/admin/, then the relative path to stuff.txt would be: docs/stuff.txt
Note, PWD + relative path = absolute path.
Cool, awesome. Now, I wrote some scripts which check if a file exists.
os.chdir("C:/users/admin/docs")
os.path.exists("stuff.txt")
This returns TRUE if stuff.txt exists and it works.
Now, instead if I write,
os.path.exists("C:/users/admin/docs/stuff.txt")
This also returns TRUE.
Is there a definite time when we need to use one over the other? Is there a methodology for how python looks for paths? Does it try one first then the other?
Thanks!
If you don't know where the user will be executing the script from, it is best to compute the absolute path on the user's system using os and __file__.
__file__ is a global variable set on every Python script that returns the relative path to the *.py file that contains it.
import os
my_absolute_dirpath = os.path.abspath(os.path.dirname(__file__))
The biggest consideration is probably portability. If you move your code to a different computer and you need to access some other file, where will that other file be? If it will be in the same location relative to your program, use a relative address. If it will be in the same absolute location, use an absolute address.
If I have a file test.py that resides in some directory, how can I find out from test.py what directory it is in? os.path.curdir will give the current directory but not the directory where the file lives. If I invoke test.py from some directory foo, os.curdir will return foo but not the path of test.py.
thanks.
Here's how to get the directory of the current file:
import os
os.path.abspath(os.path.dirname(__file__))
the answer is to use:
__file__
which returns a relative path.
os.path.abspath(__file__)
can be used to get the full path.
The answers so far have correctly pointed you to os.path.abspath, which does exactly the job you requested. However don't forget that os.path.normpath and os.path.realpath can also be very useful in this kind of tasks (to normalize representation, and remove symbolic links, respectively) in many cases (whether your specific use case falls among these "many" is impossible to tell from the scant info we have, of course;-).
import os
dirname, filename = os.path.split(os.path.abspath(__file__))
os.path has lots of tools for dealing with paths and getting information about paths.
Particularly, you want:
os.path.abspath