Это может походить на вопрос о новичке, но это не. Некоторые общие подходы не работают во всех случаях:
Это означает использовать path = os.path.abspath(os.path.dirname(sys.argv[0]))
, но это не работает, если Вы работаете из другого сценария Python в другом каталоге, и это может произойти в реальной жизни.
Это означает использовать path = os.path.abspath(os.path.dirname(__file__))
, но я нашел, что это не работает:
py2exe
не имеет a __file__
атрибут, но существует обходное решениеexecute()
существует нет __file__
атрибутNameError: global name '__file__' is not defined
Связанные вопросы с неполными ответами:
Я ищу универсальное решение, то, которое работало бы всего выше вариантов использования.
Вот результат тестового сценария:
a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz
b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz
#! /usr/bin/env python
import os, sys
print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print
execfile("subdir/b.py")
#! /usr/bin/env python
import os, sys
print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print
C:.
| a.py
\---subdir
b.py
Вы не можете напрямую определить местоположение основного выполняемого скрипта. В конце концов, иногда сценарий вообще не создавался из файла. Например, он может исходить от интерактивного интерпретатора или динамически сгенерированного кода, хранящегося только в памяти.
Однако вы можете надежно определить местоположение модуля, поскольку модули всегда загружаются из файла. Если вы создадите модуль со следующим кодом и поместите его в тот же каталог, что и ваш основной сценарий, тогда основной сценарий может импортировать модуль и использовать его для поиска самого себя.
some_path / module_locator.py:
def we_are_frozen():
# All of the modules are built-in to the interpreter, e.g., by py2exe
return hasattr(sys, "frozen")
def module_path():
encoding = sys.getfilesystemencoding()
if we_are_frozen():
return os.path.dirname(unicode(sys.executable, encoding))
return os.path.dirname(unicode(__file__, encoding))
some_path / main.py:
import module_locator
my_path = module_locator.module_path()
Если у вас есть несколько основных скриптов в разных каталогах, вам может понадобиться более одной копии module_locator.
Конечно, если ваш основной скрипт загружен каким-либо другим инструментом, который не позволяет вам импортировать модули, расположенные вместе с вашим скриптом, тогда вам не повезло. В таких случаях информация, которую вы ищете, просто не существует в вашей программе. Лучше всего сообщить об ошибке авторам инструмента.
Короткий ответ: нет гарантированного способа получить нужную информацию , однако есть эвристики, которые почти всегда работают на практике. Вы можете посмотреть Как мне найти расположение исполняемого файла в C? . В нем обсуждается проблема с точки зрения C, но предлагаемые решения легко транскрибируются в Python.