Учет меняющегося пути - PullRequest
1 голос
/ 13 ноября 2008

По отношению к другой вопрос , как вы учитываете пути, которые могут измениться? Например, если программа вызывает файл в том же каталоге, что и программа, вы можете просто использовать путь ". \ Foo.py" в * nix. Однако, по-видимому, Windows любит жестко задавать путь, например, "C: \ Python_project \ foo.py"

.

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

Я хочу, чтобы программа была кроссплатформенной, но, возможно, мне придется использовать os.name или что-то еще, чтобы определить, какой блок кода пути использовать.

Ответы [ 4 ]

4 голосов
/ 13 ноября 2008

Простой ответ: Вы определяете абсолютный путь, основанный на окружающей среде.

Что вам действительно нужно, так это несколько указателей. Существуют различные фрагменты информации о среде выполнения и среде, которые вы можете найти в разных местах стандартной библиотеки (и они, безусловно, помогают мне, когда я хочу развернуть приложение в Windows).

Итак, сначала несколько общих вещей:

  1. os.path - стандартный библиотечный модуль с большим количеством кроссплатформенных манипуляций с путями. Твой лучший друг. «Следуй за os.path», который я однажды прочитал в книге.
  2. __file__ - расположение текущего модуля.
  3. sys.executable - Местоположение работающего Python.

Теперь вы можете довольно много почерпнуть из этих трех источников все, что захотите. Функции из os.path помогут вам обойти дерево:

  • os.path.join('path1', 'path2') - объединить сегменты пути кроссплатформенным способом
  • os.path.expanduser('a_path') - найти путь a_path в домашнем каталоге пользователя
  • os.path.abspath('a_path') - преобразовать относительный путь в абсолютный
  • os.path.dirname('a_path') - получить каталог, в котором находится путь
  • много много еще ...

Таким образом, комбинируя это, например:

# script1.py
# Get the path to the script2.py in the same directory
import os
this_script_path = os.path.abspath(__file__)
this_dir_path = os.path.dirname(this_script_path)
script2_path = os.path.join(this_dir_path, 'script2.py')
print script2_path

И запустить его:

ali@work:~/tmp$ python script1.py 
/home/ali/tmp/script2.py

Теперь для вашего конкретного случая кажется, что вы немного запутались между понятием «рабочий каталог» и «каталог, в котором находится скрипт». Они могут быть одинаковыми, но они также могут быть разными. Например, «рабочий каталог» может быть изменен, и поэтому функции, которые его используют, могут иногда находить то, что ищут, но не другие. subprocess.Popen является примером этого.

Если вы всегда передаете пути абсолютно, вы никогда не попадете в проблемы с рабочим каталогом.

0 голосов
/ 13 ноября 2008

Я понял, используя os.getcwd () . Я также узнал об использовании os.path.join для автоматического определения правильного формата пути на основе ОС. Вот код:

def openNewRecord(self, event): # wxGlade: CharSheet.<event_handler>
    """Create a new, blank record sheet."""
    path = os.getcwd()
    subprocess.Popen(os.path.join(path, "TW2K_char_rec_sheet.py"), shell=True).stdout

Кажется, работает. Спасибо за идеи.

0 голосов
/ 13 ноября 2008

Что конкретно - вы имеете в виду под "вызовом файла ... foo.py"?

  1. Импорт? Если это так, путь полностью находится за пределами вашей программы. Установите переменную окружения PYTHONPATH с помощью . или c:\ или чего-либо еще на уровне оболочки. Например, вы можете написать 2-строчные сценарии оболочки для установки переменной окружения и запуска Python.

    Windows

    SET PYTHONPATH=C:\path\to\library
    python myapp.py
    

    Linux

    export PYTHONPATH=./relative/path
    python myapp.py
    
  2. ExecFile? Рассмотрите возможность использования импорта.

  3. Чтение и оценка? Рассмотрите возможность использования импорта.

Если PYTHONPATH слишком сложный, поместите ваш модуль в каталог Python lib / site-packages, где он по умолчанию помещен в PYTHONPATH.

0 голосов
/ 13 ноября 2008

Если ваш файл всегда находится в том же каталоге, что и ваша программа, то:

def _isInProductionMode():
    """ returns True when running the exe, 
        False when running from a script, ie development mode.
    """
    return (hasattr(sys, "frozen") or # new py2exe
           hasattr(sys, "importers") # old py2exe
           or imp.is_frozen("__main__")) #tools/freeze

def _getAppDir():
    """ returns the directory name of the script or the directory 
        name of the exe
    """
    if _isInProductionMode():
        return os.path.dirname(sys.executable)
    return os.path.dirname(__file__)

должно работать. Кроме того, я использовал py2exe для своего собственного приложения и не тестировал его с другими приложениями преобразования exe.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...