2016-06-29 8 views
1

Имеет ли python эквивалент пути добавления Matlab? Я знаю о sys.path.append, но это, похоже, работает только для файлов/модулей python, а не для общих файлов.Python эквивалент Matlab addpath

Предположим, у меня есть файл config.txt в C: \ Data, а текущий рабочий каталог - это что-то еще, скажем D: \ my_project.

Я хотел бы иметь код, подобный:

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

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

Очевидно, что я мог пройти путь к Foo здесь, но это очень трудно в самом прецеденте.

ответ

1

Нет, это не так. Python не работает таким образом. Файлы загружаются из текущего рабочего каталога или определенного, разрешенного пути. Нет такой вещи, как набор заранее определенных путей для загрузки произвольных файлов.

Разделение отдельных данных и программной логики является важной концепцией в Python (и большинстве других языков программирования помимо MATLAB). Ключевым принципом python является «Явное лучше, чем неявное». Убедиться, что файл данных, который вы хотите загрузить, определен явно, гораздо безопаснее, надежнее и менее подвержен ошибкам.

Так что, хотя другие показали, как вы можете взломать некоторые обходные пути, я бы очень настоятельно советовал вам не использовать этот подход. Это еще больше упростит ваш код.

+0

Я удивлен этим. Я всегда чувствовал, что Python ошибся на стороне слишком открытой и гибкой. Многие вещи в программном обеспечении часто являются плохой идеей, но все же имеют очень важные варианты использования, на ум приходит многократное наследование Python и отражение Java. – user2133814

+0

Конечно, вы можете это сделать, как показали другие люди. Python позволяет делать то, что вам не нужно делать, но в целом это затрудняет.В Python, если вы обнаружите, что вам нужно прыгать через множество обручей, чтобы что-то работать, это, как правило, хороший знак, что вы делаете то, чего не должны быть. – TheBlackCat

+0

Я не думаю, что другие показали, как это сделать. Я на самом деле хочу называть «addpath» несколько раз, а затем несколько слоев вниз читать файлы. Я также думаю, что довольно легко сделать действительно плохие вещи в Python, https://www.reddit.com/r/Python/comments/2441cv/can_you_change_the_value_of_1/, но обратите внимание, что я считаю это силой языка – user2133814

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

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

--- обновление ----

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() 
+0

Как я уже сказал в этом вопросе, это очевидное решение для этого простого случая, но на самом деле это невозможно для фактического использования. Кроме того, вы должны использовать os.path.join – user2133814

+0

@ user2133814 updated – galaxyan

4

Вы не можете добавить несколько путей, как вы бы в MATLAB.

Вы можете использовать os.chdir, чтобы изменить каталоги и файлы доступа и подкаталоги из этого каталога:

import os 

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

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

Чтобы управлять несколькими каталогами, используя менеджер контекста, который возвращается к предыдущему каталогу после окончания срока действия контекст работы:

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 
+0

Это работает, если вы хотите добавить только один путь, но с помощью Matlab вы можете добавить несколько путей, которые, вероятно, не могут быть эмулированы с помощью этого подхода. – user2133814

+0

@ user2133814 Ну, это может по крайней мере помочь вам сменить пути на лету с некоторой уверенностью в том, где именно вы находитесь в файловой системе. –

+1

@Moses Koledoye У меня была та же проблема, что и user2133814. Идея 'contextlib' хорошо работает для меня. Я должен жить с этим. Благодарю. – IanHacker

0

вы можете использовать os.chdir функциональность вместе с вашей собственной open функции, чтобы проверить все пути, которые вы хотите.

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