How can I extract the folder path from file path in Python? - python

I would like to get just the folder path from the full path to a file.
For example T:\Data\DBDesign\DBDesign_93_v141b.mdb and I would like to get just T:\Data\DBDesign (excluding the \DBDesign_93_v141b.mdb).
I have tried something like this:
existGDBPath = r'T:\Data\DBDesign\DBDesign_93_v141b.mdb'
wkspFldr = str(existGDBPath.split('\\')[0:-1])
print wkspFldr
but it gave me a result like this:
['T:', 'Data', 'DBDesign']
which is not the result that I require (being T:\Data\DBDesign).
Any ideas on how I can get the path to my file?

You were almost there with your use of the split function. You just needed to join the strings, like follows.
>>> import os
>>> '\\'.join(existGDBPath.split('\\')[0:-1])
'T:\\Data\\DBDesign'
Although, I would recommend using the os.path.dirname function to do this, you just need to pass the string, and it'll do the work for you. Since, you seem to be on windows, consider using the abspath function too. An example:
>>> import os
>>> os.path.dirname(os.path.abspath(existGDBPath))
'T:\\Data\\DBDesign'
If you want both the file name and the directory path after being split, you can use the os.path.split function which returns a tuple, as follows.
>>> import os
>>> os.path.split(os.path.abspath(existGDBPath))
('T:\\Data\\DBDesign', 'DBDesign_93_v141b.mdb')

WITH PATHLIB MODULE (UPDATED ANSWER)
One should consider using pathlib for new development. It is in the stdlib for Python3.4, but available on PyPI for earlier versions. This library provides a more object-orented method to manipulate paths <opinion> and is much easier read and program with </opinion>.
>>> import pathlib
>>> existGDBPath = pathlib.Path(r'T:\Data\DBDesign\DBDesign_93_v141b.mdb')
>>> wkspFldr = existGDBPath.parent
>>> print wkspFldr
Path('T:\Data\DBDesign')
WITH OS MODULE
Use the os.path module:
>>> import os
>>> existGDBPath = r'T:\Data\DBDesign\DBDesign_93_v141b.mdb'
>>> wkspFldr = os.path.dirname(existGDBPath)
>>> print wkspFldr
'T:\Data\DBDesign'
You can go ahead and assume that if you need to do some sort of filename manipulation it's already been implemented in os.path. If not, you'll still probably need to use this module as the building block.

The built-in submodule os.path has a function for that very task.
import os
os.path.dirname('T:\Data\DBDesign\DBDesign_93_v141b.mdb')

Here is the code:
import os
existGDBPath = r'T:\Data\DBDesign\DBDesign_93_v141b.mdb'
wkspFldr = os.path.dirname(existGDBPath)
print wkspFldr # T:\Data\DBDesign

Here is my little utility helper for splitting paths int file, path tokens:
import os
# usage: file, path = splitPath(s)
def splitPath(s):
f = os.path.basename(s)
p = s[:-(len(f))-1]
return f, p

Anyone trying to do this in the ESRI GIS Table field calculator interface can do this with the Python parser:
PathToContainingFolder =
"\\".join(!FullFilePathWithFileName!.split("\\")[0:-1])
so that
\Users\me\Desktop\New folder\file.txt
becomes
\Users\me\Desktop\New folder

I use this to change the current working directory to a folder;
from os import chdir
from os.path import realpath
from os.path import dirname
chdir(realpath(dirname(argv[0])))
chdir changes the working directory. I doubt you'll need this.
realpath follows symlinks.
dirname returns just the path
argv is the command line used to execute the program

Related

How to move up n directories in Pythonic way?

I'm looking for a pythonic way to move up n directories from a given directory.
Let's say we have the example path /data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data. If we were to move up n=2 directories we should end up at /data/python_env/lib/python3.6/site-packages.
The following works to move up n directories:
up_n = lambda path, n: '/'.join(path.split('/')[:-n])
However, it's not very readable and fails for paths on windows machines. In essence, it doesn't feel a very pythonic solution.
Is there a better, more pythonic solution, maybe using the os module?
You can use the pathlib module of the standard library:
from pathlib import Path
path = Path('/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data')
levels_up = 2
print(path.parents[levels_up-1])
# /data/python_env/lib/python3.6/site-packages
how about iterating with os.path.dirname:
import os
s = "/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data"
for _ in range(2):
s = os.path.dirname(s)
print(s)
prints:
/data/python_env/lib/python3.6/site-packages
You can use python os.path module for this:
>>> p = '/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data'
>>> os.path.normpath(os.path.join(p, "..", ".."))
'/data/python_env/lib/python3.6/site-packages'
Or generically for n,
os.path.normpath(os.path.join(*([p]+[".."]*n)))
This way, you don't care it is Windows \ or UNIX / to be used. Python should handle this well. And, you got a one-liner.
One solution to this could take advantage of the shorthand that .. is the parent directory. So, using pathlib you could write
from pathlib import Path
up_n = lambda orig, n: Path(orig).joinpath('/'.join(['..']*n))
For Python 3.4+, pathlib is probably the best choice.
That said, here's something that will also work in older versions (including Python 2.x):
import os
def up_n(path, n):
components = os.path.normpath(path).split(os.sep)
return os.sep.join(components[:-n])
if __name__ == '__main__':
path = '/data/python_env/lib/python3.6/site-packages/matplotlib/mpl-data'
result = up_n(path, 2)
print(result) # -> \data\python_env\lib\python3.6\site-packages

Accessing the filepath where I called python from

I would like to use the filepath of where I called Python from, but I have not found the solution for this yet (perhaps I'm bad at searching).
Example:
Contents of foo.py:
import sys
print(sys.path)
$ pwd
/Here
$ python3 folder1/foo.py
'/Here/folder1'
This is the result I currently get, but I would like to have access to '/Here'.
Save it to a variable
import os
pypath = os.getcwd()
In general the os module will be useful for these types of things and if you want to look at all the files in the current directory(path) then its os.listdir("."), note the "." will equal os.listdir()
You need to use os.getcwd() from os module. sys.path contains list of paths in which python will search for the modules that you are importing

Iterating over python files in a given directory and importing them?

I'm working on a little pet project in python, and I want to be able to write external modules and dynamically import them. So far, I've got something like this:
def getModules(self):
os.chdir(moduleDir)
for module in os.listdir():
#code goes here to import
#also append to a list for use later on
I'd use import module, but that just gives a Syntax Error.
You can use importlib.import_module() like this:
import importlib
my_modules = []
def getModules(self):
os.chdir(moduleDir)
for module in os.listdir():
my_module = importlib.import_module(module[:-3]) # Or: module.split('.')[0]
my_modules.append(my_module)
Example:
Let's say we have a module a that contains the following function:
def fn():
print("Hello World")
The following is the result:
>>> import importlib
>>>
>>> my_module = importlib.import_module('a') # Note: 'a' without '.py'
>>>
>>> my_module.fn()
Hello World
You should use the __import__ function. Something like this will help,
def getModules(self):
modules = []
os.chdir(moduleDir)
for module in os.listdir('.'):
m = __import__(module.split('.')[0]) # Assuming your listdir() gives .py files
modules.append(m)
A still better choice would be importlib.import_module() which is a wrapper around __import__. It's got a similar syntax to __import__. Of course, you need to import importlib.

Import set of builtin functions from a python file to another python file

I have set of inbuilt functions in 'pythonfile1.py' located at '/Users/testuser/Documents', the file contains
import os
import sys
import time
Now i want to import 'pythonfile1.py' to 'pythonfile2.py', which is located at '/Users/testuser/Documents/execute'
I have tried with my following code and it didn't work:
import sys
sys.path[0:0] = '/Users/testuser/Documents'
import pythonfile1.py
print os.getcwd()
I want it to print the current working directory
Your question is a bit unclear. Basically, there are two things 'wrong'.
First, your import statement is broken:
import pythonfile1.py
This specifies a file name, not a module name - modules don't contain dots and extensions. This is important because dots indicate sub-modules of packages. Your statement is trying to import module py from package pythonfile1. Change it to
import pythonfile1
Second, there's no need to fetch builtins from another module. You can just import them again.
# pythonfile1
import os
print 'pythonfile1', os.getcwd() # assuming py2 syntax
# pythonfile2
import os
print 'pythonfile2', os.getcwd()
If you really want to use os from pythonfile1, you can do so:
# pythonfile2
import os
import pythonfile1
print 'pythonfile2', os.getcwd()
print 'pythonfile1->2', pythonfile1.os.getcwd()
Note that os and pythonfile1.os in pythonfile2 are the exact same module.
if you want to import stuff from another file, you should use python modules.
If you will create file named init.py then the execute folder becomes a module.
After that you can use
from .pythonfile1 import function_name
or you can use
from .pythonfile1 import *
which imports all, but better solution is name everything you want to use explicitly
you can find more about modules in documentation

Import Variable from Python FilePath

I'm writing a clean up script from one of our applications and I need a few variables from a python file in a separate directory.
Now normally I would go:
from myfile import myvariable
print myvariable
However this doesn't work for files outside of the directory. I'd like a more targeted solution than:
sys.path.append('/path/to/my/dir)
from myfile import myvariable
As this directory has a lot of other files, unfortunately it doesn't seem like module = __import__('/path/to/myfile.py') works either. Any suggestions. I'm using python 2.7
EDIT, this path is unfortunately a string from os.path.join(latest, "myfile.py")
You can do a more targeted import using the imp module. While it has a few functions, I found the only one that allowed me access to internal variables was load_source.
import imp
import os
filename = 'variables_file.py'
path = '/path_to_file/'
full_path = os.path.join(path_to_file, filename)
foo = imp.load_source(filename, full_path)
print foo.variable_a
print foo.variable_b
...

Categories