Это может показаться вопросом новичка, но это не так. Некоторые общие подходы работают не во всех случаях:
sys.argv [0]
Это означает использование path = os.path.abspath(os.path.dirname(sys.argv[0]))
, но это не работает, если вы запускаете из другого скрипта Python в другом каталоге, и это может случиться в реальной жизни.
__файл__
Это означает использование path = os.path.abspath(os.path.dirname(__file__))
, но я обнаружил, что это не работает:
py2exe
не имеет__file__
атрибута, но есть обходной путь- Когда вы запускаете из IDLE с
execute()
нет__file__
атрибута - OS X 10.6, где я получаю
NameError: global name '__file__' is not defined
Связанные вопросы с неполными ответами:
- Python - Найти путь к файлу, который выполняется
- Путь к текущему файлу зависит от того, как я выполняю программу
- Как узнать путь запуска скрипта в Python?
- Изменить каталог на каталог скрипта Python
Я ищу общее решение , которое будет работать во всех вышеупомянутых случаях использования.
Обновить
Вот результат теста:
Вывод python a.py (в Windows)
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
a.py
#! /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")
подкаталог / 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
NameError: global name '__file__' is not defined
использую файл, и это не внутри IDLE. Подумайте, что__file__
определяется только внутри модулей.__file__
имеет ничего общего с Unicode. Я не знаю, почему__file__
это не определено, но я ищу общее решение, которое будет работать во всех случаях.some_path/module_locator.py
вместо?Во-первых, вам нужно импортировать из
inspect
иos
Далее, где вы хотите найти исходный файл, вы просто используете
источник
NameError: global name '__file__' is not defined
(другое решение вызвало это).lambda:_
. Это сработало для меня - не уверен, что всегда будет работать.lambda:0
вероятно , работает быстрее некоторой несоизмеримо малым количеством (или , возможно , не так уж мало ... может быть нагрузка немедленно или что - то еще быстрее0
против нагрузки глобальной для_
?) Спорно ли это чище и проще для чтения или даже более умным / затемнить.getsourcefile(lambda:0)
будет бессмысленным и просто вернется,None
если вы попытаетесь запустить его в интерактивном режиме (так какlambda
его не будет в любом исходном файле). Если вы хотите знать, откуда другая функция или объект приходит в интерактивной среде, может быть,abspath(getsourcefile(thatFunctionOrObject))
будет более полезным для вас?это решение является надежным даже в исполняемых файлах
источник
entry_point: console_script
, но ни один из других ответов.Я столкнулся с подобной проблемой, и я думаю, что это может решить проблему:
Это работает для обычных скриптов и в режиме ожидания. Все, что я могу сказать, это попробовать это для других!
Мое типичное использование:
Теперь я использую __modpath__ вместо __file__.
источник
__modpath__
их следует переименовывать. Вам также, вероятно, не нужноglobal
утверждение. В противном случае +1!module_path()
. то естьmodule_path(lambda _: None)
который не зависит от другого содержания сценария, в котором он находится.lambda _: None
и использовал его в течение почти двух последних лет, но только сейчас я обнаружил, что могу сократить его до простоlambda:0
. Есть ли какая-то конкретная причина, по которой вы предложили форму, которую вы указали, с игнорируемым аргументом_
, а не без аргумента вообще? Есть ли что-то превосходное вNone
префиксе с пробелом, а не просто0
? Они оба одинаково загадочны, я думаю, только один имеет длину 8 символов, а другой - 14 символов.lambda _:
эта функция принимает один аргумент, аlambda:
другая - не принимает. Это не имеет значения, так как функция никогда не вызывается. Также не имеет значения, какое возвращаемое значение используется. Я думаю, что я выбрал,None
потому что в то время, казалось, это указывало на то, что это была функция «ничего не делать, никогда не вызываться» лучше. Пространство перед ним не является обязательным, и опять же там только для улучшения читабельности (всегда пытаться следовать PEP8 формирует привычку).lambda
тем, чтобы использовать его для чего-то, что никогда не предназначалось. Если бы вы следовали PEP8, я думаю, что правильного содержания для него было быpass
, нетNone
, но неуместно помещать заявление в alambda
, так что вы должны вставить что-то со значением. Есть несколько допустимых двухсимвольных значений, которые вы можете вставить, но я думаю, что единственно допустимые односимвольные значения, которые вы можете вставить, это 0-9 (или однозначное имя переменной, назначенное внеlambda
.). Я считаю, что0
лучше всего указывать на пустоту 0- 9.Короткий ответ: не существует гарантированного способа получения необходимой информации , однако есть эвристические методы, которые практически всегда работают на практике. Вы можете посмотреть, как найти расположение исполняемого файла в C? , В нем обсуждается проблема с точки зрения Си, но предложенные решения легко транскрибируются в Python.
источник
См. Мой ответ на вопрос « Импортирование модулей из родительской папки» для получения соответствующей информации, в том числе почему мой ответ не использует ненадежную
__file__
переменную. Это простое решение должно быть совместимо с различными операционными системами в качестве модулейos
иinspect
входить в состав Python.Во-первых, вам нужно импортировать части модулей inspect и os .
Затем используйте следующую строку в любом другом месте, где это необходимо в вашем коде Python:
Как это устроено:
Из встроенного модуля
os
(описание ниже)abspath
инструмент импортируется.Затем
getsourcefile
(описание ниже) импортируется из встроенного модуляinspect
.abspath(path)
возвращает абсолютную / полную версию пути к файлуgetsourcefile(lambda:0)
каким-то образом получает внутренний исходный файл объекта функции lambda, поэтому возвращается'<pyshell#nn>'
в оболочку Python или возвращает путь к файлу кода Python, выполняемого в данный момент.Использование
abspath
в результатеgetsourcefile(lambda:0)
должно убедиться, что сгенерированный путь к файлу является полным путем к файлу Python.Это объясненное решение изначально было основано на коде из ответа в разделе Как получить путь к текущему исполняемому файлу в Python? ,
источник
Вы просто позвонили:
вместо того:
abspath()
дает вам абсолютный путьsys.argv[0]
(имя файла, в котором находится ваш код) иdirname()
возвращает путь к каталогу без имени файла.источник
Это должно сделать кросс-платформенное решение (если вы не используете интерпретатор или что-то в этом роде):
sys.path[0]
каталог, в котором находится ваш вызывающий скрипт (в первую очередь он ищет модули, которые будут использоваться этим скриптом). Мы можем взять имя файла самого концаsys.argv[0]
(что я и сделалos.path.basename
).os.path.join
просто склеивает их кросс-платформенным способом.os.path.realpath
просто удостоверимся, что если мы получим какие-либо символические ссылки с именами, отличными от самого скрипта, мы получим настоящее имя скрипта.У меня нет Mac; Итак, я не проверял это на одном. Пожалуйста, дайте мне знать, если это работает, как кажется, должно. Я проверил это в Linux (Xubuntu) с Python 3.4. Обратите внимание, что многие решения этой проблемы не работают на компьютерах Mac (поскольку я слышал, что их
__file__
нет на компьютерах Mac).Обратите внимание, что если ваш скрипт является символической ссылкой, он даст вам путь к файлу, на который он ссылается (а не путь к символической ссылке).
источник
Вы можете использовать
Path
изpathlib
модуля:Вы можете использовать вызов, чтобы
parent
пойти дальше по пути:источник
__file__
переменная, которая может быть ненадежной (не всегда полный путь к файлу, не работает в каждой операционной системе и т. Д.), Как часто упоминают пользователи StackOverflow. Изменение ответа, чтобы не включать его, вызовет меньше проблем и будет более совместимым. Для получения дополнительной информации см. Stackoverflow.com/a/33532002/3787376 .Если код приходит из файла, вы можете получить его полное имя
Вы также можете получить имя функции как
f_code.co_name
источник
Просто добавьте следующее:
Или:
источник
Мое решение:
источник
источник
'__file__'
не должно быть строки, во-вторых, если вы это сделали__file__
, это будет работать только для файла, в котором находится эта строка кода, а не для файла, который выполняется?