Ответы:
Вы можете использовать, __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",)"