Reputation: 66637
this code is get the templates/blog1/page.html in b.py:
path = os.path.join(os.path.dirname(__file__), os.path.join('templates', 'blog1/page.html'))
but i want to get the parent dir location:
aParent
|--a
| |---b.py
| |---templates
| |--------blog1
| |-------page.html
|--templates
|--------blog1
|-------page.html
and how to get the aParent location
thanks
updated:
this is right:
dirname=os.path.dirname
path = os.path.join(dirname(dirname(__file__)), os.path.join('templates', 'blog1/page.html'))
or
path = os.path.abspath(os.path.join(os.path.dirname(__file__),".."))
Upvotes: 178
Views: 286119
Reputation: 5234
The newer pathlib
module, as mentioned in other answers, is, of course, the nicest method to parse and build paths, but you can get the parent also easily with the older os.path
module:
os.path.split('a/b/c') # returns: ('a/b', 'c')
If you don't want the full path of the parent a/b, but just the name b, just call os.path.split a second time.
Upvotes: 1
Reputation: 11
from os.path import basename, dirname
basename(dirname('foo/bar/foo_bar'))
Upvotes: 1
Reputation: 4633
Use relative path with the pathlib
module in Python 3.4+:
from pathlib import Path
Path(__file__).parent
You can use multiple calls to parent
to go further in the path:
Path(__file__).parent.parent
As an alternative to specifying parent
twice, you can use:
Path(__file__).parents[1]
Upvotes: 79
Reputation: 1045
Use the following to jump to previous folder:
os.chdir(os.pardir)
If you need multiple jumps a good and easy solution will be to use a simple decorator in this case.
Upvotes: 2
Reputation: 10048
I tried:
import os
os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))), os.pardir))
Upvotes: 0
Reputation: 4916
Here is another relatively simple solution that:
dirname()
(which does not work as expected on one level arguments like "file.txt" or relative parents like "..")abspath()
(avoiding any assumptions about the current working directory) but instead preserves the relative character of pathsit just uses normpath
and join
:
def parent(p):
return os.path.normpath(os.path.join(p, os.path.pardir))
# Example:
for p in ['foo', 'foo/bar/baz', 'with/trailing/slash/',
'dir/file.txt', '../up/', '/abs/path']:
print parent(p)
Result:
.
foo/bar
with/trailing
dir
..
/abs
Upvotes: 3
Reputation: 809
I think use this is better:
os.path.realpath(__file__).rsplit('/', X)[0]
In [1]: __file__ = "/aParent/templates/blog1/page.html"
In [2]: os.path.realpath(__file__).rsplit('/', 3)[0]
Out[3]: '/aParent'
In [4]: __file__ = "/aParent/templates/blog1/page.html"
In [5]: os.path.realpath(__file__).rsplit('/', 1)[0]
Out[6]: '/aParent/templates/blog1'
In [7]: os.path.realpath(__file__).rsplit('/', 2)[0]
Out[8]: '/aParent/templates'
In [9]: os.path.realpath(__file__).rsplit('/', 3)[0]
Out[10]: '/aParent'
Upvotes: 0
Reputation: 185842
You can apply dirname repeatedly to climb higher: dirname(dirname(file))
. This can only go as far as the root package, however. If this is a problem, use os.path.abspath
: dirname(dirname(abspath(file)))
.
Upvotes: 231
Reputation: 1222
os.pardir
is a better way for ../
and more readable.
import os
print os.path.abspath(os.path.join(given_path, os.pardir))
This will return the parent path of the given_path
Upvotes: 9
Reputation: 2116
A simple way can be:
import os
current_dir = os.path.abspath(os.path.dirname(__file__))
parent_dir = os.path.abspath(current_dir + "/../")
print parent_dir
Upvotes: 6
Reputation: 20556
os.path.abspath
doesn't validate anything, so if we're already appending strings to __file__
there's no need to bother with dirname
or joining or any of that. Just treat __file__
as a directory and start climbing:
# climb to __file__'s parent's parent:
os.path.abspath(__file__ + "/../../")
That's far less convoluted than os.path.abspath(os.path.join(os.path.dirname(__file__),".."))
and about as manageable as dirname(dirname(__file__))
. Climbing more than two levels starts to get ridiculous.
But, since we know how many levels to climb, we could clean this up with a simple little function:
uppath = lambda _path, n: os.sep.join(_path.split(os.sep)[:-n])
# __file__ = "/aParent/templates/blog1/page.html"
>>> uppath(__file__, 1)
'/aParent/templates/blog1'
>>> uppath(__file__, 2)
'/aParent/templates'
>>> uppath(__file__, 3)
'/aParent'
Upvotes: 69
Reputation: 816302
os.path.dirname(os.path.abspath(__file__))
Should give you the path to a
.
But if b.py
is the file that is currently executed, then you can achieve the same by just doing
os.path.abspath(os.path.join('templates', 'blog1', 'page.html'))
Upvotes: 15
Reputation: 123791
May be join two ..
folder, to get parent of the parent folder?
path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)),"..",".."))
Upvotes: 3