как я могу получить текущий каталог исполняемого файла в py2exe? - PullRequest
17 голосов
/ 19 февраля 2010

Я использую этот фрагмент кода в своем скрипте для кросс-платформенного определения, откуда именно он выполняется:

SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))

Довольно просто.Затем я продолжаю использовать SCRIPT_ROOT в других областях моего сценария, чтобы убедиться, что все относительно правильно.Моя проблема возникает, когда я запускаю его через py2exe, потому что сгенерированный исполняемый файл не устанавливает __file__, поэтому мой скрипт ломается.Кто-нибудь знает, как это исправить или обойти?

Ответы [ 4 ]

22 голосов
/ 19 февраля 2010

Вот справочник по документации py2exe , и вот соответствующие пункты:

  • sys.executable - полный путь к exe-файлу.
  • Первый элемент в sys.argv - это полный путь к исполняемому файлу, остальные - аргументы командной строки.
  • sys.frozen существует только в исполняемом файле. Он установлен на «console_exe» для исполняемого файла консоли, «windows_exe» для исполняемого файла GUI без консоли и на «dll» для сервера dll inprocess.
  • __file__ не определено (вы можете использовать вместо sys.argv [0])

Из этих документов не очевидно, являются ли exe-файл и исполняемый файл одним и тем же, и, следовательно, являются ли sys.executable и sys.argv[0] одним и тем же. Глядя на код, который работал как для script.py, так и для py2exe_executable.exe в прошлый раз, когда мне пришлось это сделать, я обнаружил что-то вроде:

if hasattr(sys, 'frozen'):
    basis = sys.executable
else:
    basis = sys.argv[0]
required_folder = os.path.split(basis)[0]

Как я уже говорил, это сработало, но я не помню, почему я подумал, что это необходимо, вместо того, чтобы просто использовать sys.argv[0].

Использование только basis было достаточным для выполняемой работы (чтение файлов в этом каталоге). Для более постоянной записи разделите что-то вроде os.path.realpath(basis).

Обновление На самом деле сделал тест; превосходит догадки и кресло понтификации: -)

Резюме: Игнорировать sys.frozen, игнорировать sys.executable, безоговорочно использовать sys.argv [0].

Данные:

=== foo.py ===

# coding: ascii
import sys, os.path
print 'sys has frozen:', hasattr(sys, 'frozen')
print 'using sys.executable:', repr(os.path.dirname(os.path.realpath(sys.executable)))
print 'using sys.argv[0]:',    repr(os.path.dirname(os.path.realpath(sys.argv[0]   )))

=== setup.py ===

from distutils.core import setup
import py2exe
setup(console=['foo.py'])

=== Результаты ===

C:\junk\so\py2exe>\python26\python foo.py
sys has frozen: False
using sys.executable: 'C:\\python26'
using sys.argv[0]: 'C:\\junk\\so\\py2exe' # where foo.py lives

C:\junk\so\py2exe>dist\foo
sys has frozen: True
using sys.executable: 'C:\\junk\\so\\py2exe\\dist'
using sys.argv[0]: 'C:\\junk\\so\\py2exe\\dist' # where foo.exe lives
8 голосов
/ 04 июля 2013

Py2exe не определяет __file__: http://www.py2exe.org/index.cgi/Py2exeEnvironment

ОП запросил дружественную для py2exe версию:

SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))

Лучший ответ - определить, заморожен ли питон вexe, py2exe имеет документацию по этому вопросу: http://www.py2exe.org/index.cgi/HowToDetermineIfRunningFromExe

import imp, os, sys

def main_is_frozen():
   return (hasattr(sys, "frozen") or # new py2exe
           hasattr(sys, "importers") # old py2exe
           or imp.is_frozen("__main__")) # tools/freeze

def get_main_dir():
   if main_is_frozen():
       return os.path.dirname(sys.executable)
   return os.path.dirname(os.path.realpath(__file__))

SCRIPT_ROOT = get_main_dir()

Так как питон EAFP , вот EAFP версия ...

try:
   if sys.frozen or sys.importers:
      SCRIPT_ROOT = os.path.dirname(sys.executable)
except AttributeError:
   SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))

Ура!

2 голосов
/ 19 февраля 2010

Попробуйте это:

import os
import sys
os.path.realpath(os.path.dirname(sys.argv[0]))
0 голосов
/ 02 июля 2019

sys.argv[0] - это надежный способ получить путь, поскольку он даст тот же результат независимо от того, запускается ли он как скрипт или исполняемый файл. , Получить справочник os.path.dirname(sys.argv[0])

comparison between file and exe

...