user2133814
user2133814

Reputation: 2651

Python equivalent of Matlab addpath

Does python have an equivalent to Matlab's addpath? I know about sys.path.append, but that only seems to work for python files/modules, not for general files.

Suppose I have a file config.txt in C:\Data and the current working directory is something else, say D:\my_project.

I would like to have code similar to:

def foo():
    with open('config.txt') as f:
        print(f.read())

def main():
    addpath(r'C:\Data')
    foo()

Obviously I could pass the path to foo here, but that is very difficult in the actual use case.

Upvotes: 4

Views: 10450

Answers (5)

bamboopu
bamboopu

Reputation: 11

sorry, I made a mistake.

I guess you can use this to solve it. (as a stack newbee, I hope it helps)

import sys
sys.path.append(r'path')

Upvotes: 1

TheBlackCat
TheBlackCat

Reputation: 10308

No, it doesn't. Python doesn't work this way. Files are loaded from the current working directory or a specific, resolved path. There is no such thing as a set of pre-defined paths for loading arbitrary files.

Keeping data and program logic separate is an important concept in Python (and most other programming languages besides MATLAB). An key principle of python is "Explicit is better than implicit." Making sure the data file you want to load is defined explicitly is much safer, more reliable, and less error-prone.

So although others have shown how you can hack some workarounds, I would very, very strongly advise you to not use this approach. It is going to make maintaining your code much harder.

Upvotes: 3

Him
Him

Reputation: 5551

You can use the os.chdir functionality along with your own open function to check all the paths you want to.

class FileOpener(object):
    def __init__(self):
        self.paths = []
    def add_path(self, path):
        self.paths.append(path)
    def __open_path(self, path, *args, **kwargs):
        old_path = os.getcwd()
        try:
            os.chdir(path)
            return open(*args, **kwargs)
        except:
            pass
        finally:
            os.chdir(old_path)
    def open(self, *args, **kwargs):
        for path in self.paths + [os.getcwd()]:
            f = self.__open_path(path, *args, **kwargs)
            if f is not None:
                return f
        raise IOError("no such file")

my_file_opener = FileOpener()
my_file_opener.add_path("C:/Data")
my_file_opener.add_path("C:/Blah")
my_file_opener.open("some_file") # checks in C:/Data, C:/Blah and then the current working directory, returns the first file named "some_file" that it finds, and raises an IOError otherwise

Upvotes: 1

Moses Koledoye
Moses Koledoye

Reputation: 78554

You can't add multiple paths like you would in matlab.

You can use os.chdir to change directories, and access files and sub-directories from that directory:

import os

def foo():
    with open('config.txt') as f:
        print(f.read())

def main():
    os.chdir(r'C:\Data')
    foo()

To manage multiple directories, using a context manager that returns to the previous directory after the expiration of the context works:

import contextlib
import os

@contextlib.contextmanager
def working_directory(path):
    prev_cwd = os.getcwd()
    os.chdir(path)
    yield
    os.chdir(prev_cwd)

def foo():
    with open('config.txt') as f:
        print(f.read())

def main():
    with working_directory(r'C:\Data'):
        foo()
    # previous working directory

Upvotes: 4

galaxyan
galaxyan

Reputation: 6121

def foo(prefix):
    path = prefix + 'config.txt'
    with open(path) as f:
        print(f.read())

def main():
    foo(r'C:\Data\')

---update----

import os

class changeFileDir:
    def __init__(self, path):
        self.path= os.path.expanduser(path)

    def __enter__(self):
        self.savedPath = os.getcwd()
        os.chdir(self.path)

    def __exit__(self, etype, value, traceback):
        os.chdir(self.savedPath)


with changeFileDir(r'C:\Data'):
    foo()

Upvotes: 0

Related Questions