Relative path in Python - python

I'm writing some python code to generate the relative path. Situation need to be considered:
Under the same folder. I want "." or ".\", both of tham are ok for me.
Other folder. I want like ".\xxx\" and "..\xxx\xxx\"
os.path.relpath() will generate the relative path, but without .\ at the beginning and \ in the end. We can add \ in the end by using os.path.join(dirname, ""). But i can't figure out how to add ".\" at the beginning without impacting the first case when they are under the same folder and "..\xxx\xxx\".

It will give you relative path
import os
dir = os.path.dirname(__file__)
filename = os.path.join(dir,'Path')

The relpath() function will produce the ".." syntax given the appropriate base to start from (second parameter). For instance, supposing you were writing something like a script generator that produces code using relative paths, if the working directory is as the second parameter to relpath() as below indicates, and you want to reference in your code another file in your project under a directory one level up and two deep, you'll get "../blah/blah".. In the case where you want to prefix paths in the same folder, you can simply do a join with ".". That will produce a path with the correct OS specific separator.
print(os.path.relpath("/foo/bar/blah/blah", "/foo/bar/baz"))
>>> ../blah/blah
print(os.path.join('.', 'blah'))
>>> ./blah

Related

list of jpeg files in nested subdirectories

I use the following python code to get list of jpg files in nested subdirectories which are in parent directory.
import glob2,os
all_header_files = glob2.glob(os.path.join('Path/to/parent/directory','/**/*.jpg'))
However, I get nothing but when I cd into the parent directory and I use the following python code then I get the list of jpeg files.
import glob2
all_header_files = glob2.glob('./**/*.jpg')
How can I get the result with the absolute path?(first version)
You have an extra slash.
The os.path.join will insert the filepath separators for you, so you should think of it as this to get the correct directory
join('Path/to/parent directory' , '**/*.jpg')
Even more accurately,
parent = os.path.join('Path', 'to', 'parent directory')
os.path.join(parent, '**/*.jpg')
If you are trying to use your Home directory, see os.path.expanduser
In [10]: import os, glob
In [11]: glob.glob(os.path.join('~', 'Downloads', "**/*.sh"))
Out[11]: []
In [12]: glob.glob(os.path.expanduser(os.path.join('~', 'Downloads', "**/*.sh")))
Out[12]:
['/Users/name/Downloads/dir/script.sh']
You should not join with the trailing slash as you'll end up with the root. You can debug by printing out the resulting path before passing it to glob.
Try to change your code like this (note the dot):
import glob2,os
all_header_files = glob2.glob(os.path.join('Path/to/parent directory','./**/*.jpg'))
os.path.join() joins paths in an intelligent way.
os.path.join('Path/to/anything','/**/*.jpg'))
resolves to '/**/*.jpg' since '/**/*.jpg' is any path, ever.
Change the '/**/*.jpg' to '**/*.jpg' and it should work.
In cases like this, I recommend to always try out the result of a certain function within the python command line. At least, this is how I found out the issue here.
The problem with the code you have posted lies in the use of os.path.join.
In the documentation it says for os.path.join(path, *paths):
If a component is an absolute path, all previous components are thrown away and joining continues from the absolute path component.
In your case, the component /**/*.jpg is an absolute path, as it starts with a /. Consequently your initial input /Path/to/parent directory is being truncated by the call to the join function. (https://docs.python.org/3.5/library/os.path.html#os.path.join)
I have locally tested the joining part with python3 and for me it is the case, that using os.path.join(any_path, "/**/*.pdf") returns the string '/**/*.pdf'.
The fix for this error is:
import glob2,os
all_header_files = glob2.glob(os.path.join('Path/to/parent directory','**/*.jpg'))
This returns the path 'Path/to/parent directory/**/*.jpg'

Add and change relative directory to an existed path (python script)

There is a default path in a function:
def function(directory):
path = ('/a/b/c/d/e/f/g')
newdirectory = (This is the part I am asking)
I call this function:
from xxx import function:
p('../../x/y')
I need to get a new directory 'newdirectory', which is supposed to be 'a/b/c/d/e/x/y', in order to proceed to the next step, but I don't know how to add the relative directory to an absolute directory and generate a new absolute directory
Use os.path.join() to join the two path strings together, and os.path.abspath() to resolve the relative parts into one absolute path.
import os
print os.path.abspath(os.path.join('/a/b/c/d/e/f/g', '../../x/y'))

Extracting penultimate folder name from path

Does anyone know a clever way to extract the penultimate folder name from a given path?
eg folderA/folderB/folderC/folderD
-> I want to know what the name of folderC is, I don't know the names of the other folders and there may be a variable number of directories before folderC but it's always the 2nd to last folder.
everything i come up with seems too cumbersome (eg getting name of folderD using basename and normpath, removing this from path string, and the getting folderC
cheers, -m
There isn't a good way to skip directly to portions within a path in a single call, but what you want can be easily done like so:
>>> os.path.basename(os.path.dirname('test/splitting/folders'))
'splitting'
Alternatively, if you know you'll always be on a filesystem with '/' delineated paths, you can just use regular old split() to get there directly:
>>> 'test/splitting/folders'.split('/')[-2]
'splitting'
Although this is a bit more fragile. The dirname+basename combo works with/without a file at the end of the path, where as the split version you have to alter the index
yep, there sure is:
>>> import os.path
>>> os.path.basename(os.path.dirname("folderA/folderB/folderC/folderD"))
'folderC'
That is, we find the 'parent directory' of the named path, and then extract the filename of the resulting path from that.

How to generate path of a directory in python

I have a file abc.py under the workspace dir.
I am using os.listdir('/home/workspace/tests') in abc.py to list all the files (test1.py, test2.py...)
I want to generate the path '/home/workspace/tests' or even '/home/workspace' instead of hardcoding it.
I tried os.getcwd() and os.path.dirname(os.path.abspath(____file____)) but this instead generates the path where the test script is being run.
How to go about it?
The only way you can refer to a specific folder from which you don't relate in any way and you don't want to hardcode it, is to pass it as a parameter to the script (search for: command line argument)
I think you are asking about how to get the relative path instead of absolute one.
Absolute path is the one like: "/home/workspace"
Relative looks like the following "./../workspace"
You should construct the relative path from the dir where your script is (/home/workspace/tests) to the dir that you want to acces (/home/workspace) that means, in this case, to go one step up in the directory tree.
You can get this by executing:
os.path.dirname(os.path.join("..", os.path.abspath(__file__)))
The same result may be achieved if you go two steps up and one step down to workspace dir:
os.path.dirname(os.path.join("..", "..", "workspace", os.path.abspath(__file__)))
In this manner you actually can access any directory without knowing it's absolute path, but only knowing where it resides relatively to your executed file.

How to split path with slashes?

I have a requirement for adding and splitting path in my app.I want to work with this app on windows and linux.Here is my code to add paths
path = os.path.join(dir0,dir1,dir2,fn)
But when i am splitting with slashes i am facing problems .Because
the path in windows like:
dir0\dir1\dir2\fn
the path in linux like
dir0/dir1/dir2/fn
Now how can i split the path with single code(with out changing the code while using other platform/platform independent)
You can use os.sep
just
import os
path_string.split(os.sep)
For more info, look the doc
os.path.join(path1[, path2[, ...]])
Join one or more path components intelligently. If any component is an absolute path, all previous components (on Windows, including the previous drive letter, if there was one) are thrown away, and joining continues. The return value is the concatenation of path1, and optionally path2, etc., with exactly one directory separator (os.sep) following each non-empty part except the last. (This means that an empty last part will result in a path that ends with a separator.) Note that on Windows, since there is a current directory for each drive, os.path.join("c:", "foo") represents a path relative to the current directory on drive C: (c:foo), not c:\foo.
Use os.path.split. It is a system independent way to split paths. Note that this only splits into (head, tail). To get all the individual parts, you need to recursively split head or use str.split using os.path.sep as the separator.

Categories