Ответы:
Вы можете использовать, __file__
чтобы получить имя текущего файла. При использовании в основном модуле это имя сценария, который был первоначально вызван.
Если вы хотите опустить часть каталога (которая может присутствовать), вы можете использовать os.path.basename(__file__)
.
__file__
не определено в интерактивном переводчике, потому что это бессмысленно. Он устанавливается реализацией импорта, поэтому, если вы используете нестандартный механизм импорта, он также может быть не установлен.
import os
это необходимо для работы. Я бы добавил это в ответ.
import os
и import os.path
полностью эквивалентны.
import sys
print sys.argv[0]
Это будет печатать foo.py
для python foo.py
, dir/foo.py
для python dir/foo.py
и т. Д. Это первый аргумент для python
. (Обратите внимание, что после py2exe это будет foo.exe
.)
python linkfile.py
, где linkfile.py
находится символическая ссылка realfile.py
, sys.argv[0]
будет 'linkfile.py'
, что может или не может быть то, что вы хотите; это конечно то, чего я ожидаю . __file__
то же самое: будет linkfile.py
. Если вы хотите найти 'realfile.py'
с 'linkfile.py'
, попробуйте os.path.realpath('linkfile.py')
.
__file__
вместо этого.
Для полноты картины я подумал, что было бы целесообразно обобщить различные возможные результаты и предоставить ссылки для точного поведения каждого из них:
__file__
является текущим исполняемым файлом, как указано в официальной документации :
__file__
путь к файлу, из которого был загружен модуль, если он был загружен из файла.__file__
Атрибут может отсутствовать для некоторых типов модулей, таких как C модули , которые статически связаны в интерпретатор; для модулей расширения, загружаемых динамически из общей библиотеки, это путь к файлу общей библиотеки.
С Python3.4 годом, на вопрос 18416 , __file__
всегда абсолютный путь, если в данный момент выполняет файл не является сценарием , который был выполнен непосредственно (не через переводчик с -m
параметром командной строки) , используя относительный путь.
__main__.__file__
(требует импорта __main__
) просто обращается к вышеупомянутому __file__
атрибуту основного модуля , например, сценария, который был вызван из командной строки.
sys.argv[0]
(требует импорта sys
) - это имя сценария, которое было вызвано из командной строки и может быть абсолютным путем, как подробно описано в официальной документации :
argv[0]
имя скрипта (зависит от операционной системы, является ли это полным путем или нет). Если команда была выполнена с использованием параметра-c
командной строки для интерпретатора,argv[0]
устанавливается строка'-c'
. Если имя интерпретатора не было передано интерпретатору Python,argv[0]
это пустая строка.
Как упоминалось в другом ответе на этот вопрос , скрипты Python, которые были преобразованы в автономные исполняемые программы с помощью таких инструментов, как py2exe или PyInstaller, могут не отображать желаемый результат при использовании этого подхода (то есть sys.argv[0]
будут содержать имя исполняемого файла, а не имя основного файла Python в этом исполняемом файле).
Если ни одна из вышеупомянутых опций не работает, возможно, из-за нерегулярной операции импорта, модуль проверки может оказаться полезным. В частности, вызов inspect.getfile(...)
on inspect.currentframe()
может работать, хотя последний будет возвращатьсяNone
при запуске в реализации без фрейма стека Python .
Если текущий скрипт является символической ссылкой, то все вышеперечисленное будет возвращать путь символической ссылки, а не путь к реальному файлу, и его os.path.realpath(...)
следует вызывать для извлечения последней.
os.path.basename(...)
может быть вызван по любому из вышеперечисленных для извлечения фактического имени файла и os.path.splitext(...)
может быть вызван по фактическому имени файла для усечения его суффикса, как в os.path.splitext(os.path.basename(...))
.
Из Python 3.4 и далее, за PEP 428 , то PurePath
класс из pathlib
модуля может быть также использован на любом из указанных выше. В частности, pathlib.PurePath(...).name
извлекает фактическое имя файла и pathlib.PurePath(...).stem
извлекает фактическое имя файла без его суффикса.
Обратите внимание, что __file__
это даст файл, в котором находится этот код, который можно импортировать и отличать от интерпретируемого основного файла. Чтобы получить основной файл, можно использовать специальный модуль __main__ :
import __main__ as main
print(main.__file__)
Обратите внимание, что это __main__.__file__
работает в Python 2.7, но не в 3.2, поэтому используйте синтаксис import-as, как описано выше, чтобы сделать его переносимым.
rPython
пакет из R
языка. Это, должно быть, исключительный случай, с которым слишком трудно разобраться.
__main__
изнутри, для использования при передаче переменных между R
и python
, поэтому было бы относительно легко установить его __main__.__file__
перед вызовом чего-либо еще, но я даже не уверен, что будет подходящим значением в этом случае.
Вышеуказанные ответы хороши. Но я нашел этот метод более эффективным, используя приведенные выше результаты.
Это приводит к фактическому имени файла сценария, а не к пути.
import sys
import os
file_name = os.path.basename(sys.argv[0])
Для современных версий Python (3.4+), Path(__file__).name
должно быть более идиоматичным. Кроме того, Path(__file__).stem
дает вам имя сценария без .py
расширения.
from pathlib import Path
сначала.
pathlib
был введен в Python 3.4, поэтому он должен работать, начиная с Python 3.4.
Предполагая, что имя файла foo.py
, приведенный ниже фрагмент
import sys
print sys.argv[0][:-3]
или
import sys
print sys.argv[0][::-1][3:][::-1]
Что касается других расширений с большим количеством символов, например имя файла foo.pypy
import sys
print sys.argv[0].split('.')[0]
Если вы хотите извлечь из абсолютного пути
import sys
print sys.argv[0].split('/')[-1].split('.')[0]
будет выводить foo
Первым аргументом в sys будет текущее имя файла, так что это будет работать
import sys
print sys.argv[0] # will print the file name
Если вы делаете необычный импорт (например, это файл опций), попробуйте:
import inspect
print (inspect.getfile(inspect.currentframe()))
Обратите внимание, что это вернет абсолютный путь к файлу.
мы можем попробовать это, чтобы получить текущее имя скрипта без расширения.
import os
script_name = os.path.splitext(os.path.basename(__file__))[0]
все эти ответы великолепны, но есть некоторые проблемы, которые вы можете не увидеть с первого взгляда.
давайте определим, что мы хотим - нам нужно имя сценария, который был выполнен, а не имя текущего модуля - поэтому __file__
будет работать, только если он используется в исполняемом сценарии, а не в импортированном модуле.
sys.argv
Также сомнительно - что если ваша программа была вызвана pytest? или бегун-пидок? или если он был назван uwsgi?
и - есть третий способ получения имени сценария, который я не видел в ответах - Вы можете проверить стек.
Другая проблема заключается в том, что Вы (или какая-либо другая программа) можете вмешиваться sys.argv
и __main__.__file__
- это может присутствовать, а может и не быть. Это может быть действительным или нет. По крайней мере, вы можете проверить, существует ли сценарий (желаемый результат)!
моя библиотека bitranox / lib_programname в github делает именно это:
__main__
присутствует ли__main__.__file__
присутствует ли__main__.__file__
действительный результат (этот сценарий существует?)тем путем, мое решение работает до сих пор с setup.py test
, uwsgi
, pytest
, pycharm pytest
, pycharm docrunner (doctest)
, dreampie
,eclipse
есть также хорошая статья в блоге об этой проблеме от Dough Hellman, "Определение имени процесса из Python"
Мое быстрое грязное решение:
__file__.split('/')[-1:][0]
os.path
для разделения имен файлов
os.path.abspath(__file__)
даст вам абсолютный путь (также relpath()
доступно).
sys.argv[-1]
даст вам относительный путь.
Начиная с Python 3.5 вы можете просто:
from pathlib import Path
Path(__file__).stem
Подробнее здесь: https://docs.python.org/3.5/library/pathlib.html#pathlib.PurePath.stem
Например, у меня есть файл в моем пользовательском каталоге, названный test.py
так:
from pathlib import Path
print(Path(__file__).stem)
print(__file__)
запустив эти выводы:
>>> python3.6 test.py
test
test.py
Exception NameError: NameError("global name '__file__' is not defined",)
"