Я использую этот бит кода в моем сценарии для точного определения межплатформенным способом, откуда точно он выполняется:
SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))
Довольно простой. Я тогда продолжаю использовать SCRIPT_ROOT
в других областях моего сценария для проверки все правильно относительно. Моя проблема происходит, когда я выполняю ее через py2exe, потому что сгенерированный исполняемый файл не устанавливает __file__
, поэтому мои повреждения сценария. Кто-либо знает, как зафиксировать или работать вокруг этого?
Вот ссылка на документацию py2exe и вот соответствующие пункты:
sys.executable
установлен на полное имя пути exe-файла. sys.argv
- полный путь к исполняемому файлу, остальные - аргументы командной строки. sys.frozen
существует только в исполняемом файле. Он устанавливается в "console_exe" для консольного исполняемого файла, в "windows_exe" для исполняемого файла с gui без консоли и в "dll" для dll-сервера внутри процесса. __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'])
=== results ===
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
Попробуйте это:
import os
import sys
os.path.realpath(os.path.dirname(sys.argv[0]))