Вы можете использовать, __file__чтобы получить имя текущего файла. При использовании в основном модуле это имя сценария, который был первоначально вызван.
Если вы хотите опустить часть каталога (которая может присутствовать), вы можете использовать os.path.basename(__file__).
Python 3.2: " Exception NameError: NameError("global name '__file__' is not defined",)"
sdaau
20
@sdaau: __file__не определено в интерактивном переводчике, потому что это бессмысленно. Он устанавливается реализацией импорта, поэтому, если вы используете нестандартный механизм импорта, он также может быть не установлен.
Свен Марнач
8
По крайней мере, для Python 2.7, я считаю, что import osэто необходимо для работы. Я бы добавил это в ответ.
@ Свен-Марнах: О, ты прав . Я делал это неправильно годами!
cdunn2001
136
import sysprint sys.argv[0]
Это будет печатать foo.pyдля python foo.py, dir/foo.pyдля python dir/foo.pyи т. Д. Это первый аргумент для python. (Обратите внимание, что после py2exe это будет foo.exe.)
@DenisMalinovsky: определить "не будет работать". Если вы позвоните python linkfile.py, где linkfile.pyнаходится символическая ссылка realfile.py, sys.argv[0]будет 'linkfile.py', что может или не может быть то, что вы хотите; это конечно то, чего я ожидаю . __file__то же самое: будет linkfile.py. Если вы хотите найти 'realfile.py'с 'linkfile.py', попробуйте os.path.realpath('linkfile.py').
Крис Морган
6
+1, потому что (а) немного аккуратнее и (б) все равно будет работать в модуле (где файловая переменная будет файлом модуля, а не исполняемым).
Роберт
Этот ответ хорош, потому что он работает и в IDLE. В качестве примечания, чтобы получить только имя файла, вы можете написать os.path.basename (sys.argv [0])
Стивен Блюен,
Что еще более важно, это не работает, кроме как из основного файла. Не используйте это, используйте __file__вместо этого.
Аполлис поддерживает Монику
ЧТО!!! Вы даже пробовали это? Точно противоположное верно. Спрашивающий спросил имя запущенного скрипта python, а не файл python, который в данный момент выполняется. Представьте, что у вас есть сценарий, который при возникновении ошибки выводит имя сценария вместе с разрешенными аргументами. Вы помещаете это в функцию, используя один из этих двух методов. В какой-то момент вы решаете перенести функцию во внешнюю библиотеку. Вы хотите напечатать имя основного скрипта или имя файла библиотеки, который выполняется?
Джон Дейган
71
Для полноты картины я подумал, что было бы целесообразно обобщить различные возможные результаты и предоставить ссылки для точного поведения каждого из них:
__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(...)).
Обратите внимание, что __file__это даст файл, в котором находится этот код, который можно импортировать и отличать от интерпретируемого основного файла. Чтобы получить основной файл, можно использовать специальный модуль __main__ :
import __main__ as main
print(main.__file__)
Обратите внимание, что это __main__.__file__работает в Python 2.7, но не в 3.2, поэтому используйте синтаксис import-as, как описано выше, чтобы сделать его переносимым.
Это работает во многих случаях, но не когда я использую rPythonпакет из Rязыка. Это, должно быть, исключительный случай, с которым слишком трудно разобраться.
Леонид
Действительно, в пакет rPython встроен интерпретатор python, что означает, что нет «основного» файла, как это бывает, когда python работает сам по себе (вы обнаружите, что такое же поведение происходит при каждом внедрении python). Он импортирует __main__изнутри, для использования при передаче переменных между Rи python, поэтому было бы относительно легко установить его __main__.__file__перед вызовом чего-либо еще, но я даже не уверен, что будет подходящим значением в этом случае.
Перкинс
42
Вышеуказанные ответы хороши. Но я нашел этот метод более эффективным, используя приведенные выше результаты.
Это приводит к фактическому имени файла сценария, а не к пути.
import sys
import os
file_name = os.path.basename(sys.argv[0])
Мне также нравится отделять расширение, поэтому я использую: os.path.splitext (os.path.basename (sys.argv [0])) [0]
RufusVS
19
Для современных версий Python (3.4+), Path(__file__).nameдолжно быть более идиоматичным. Кроме того, Path(__file__).stemдает вам имя сценария без .pyрасширения.
все эти ответы великолепны, но есть некоторые проблемы, которые вы можете не увидеть с первого взгляда.
давайте определим, что мы хотим - нам нужно имя сценария, который был выполнен, а не имя текущего модуля - поэтому __file__будет работать, только если он используется в исполняемом сценарии, а не в импортированном модуле.
sys.argvТакже сомнительно - что если ваша программа была вызвана pytest? или бегун-пидок? или если он был назван uwsgi?
и - есть третий способ получения имени сценария, который я не видел в ответах - Вы можете проверить стек.
Другая проблема заключается в том, что Вы (или какая-либо другая программа) можете вмешиваться sys.argvи __main__.__file__- это может присутствовать, а может и не быть. Это может быть действительным или нет. По крайней мере, вы можете проверить, существует ли сценарий (желаемый результат)!
моя библиотека bitranox / lib_programname в github делает именно это:
проверьте, __main__присутствует ли
проверьте, __main__.__file__присутствует ли
дает __main__.__file__действительный результат (этот сценарий существует?)
если нет: проверьте sys.argv:
есть ли в sys.argv pytest, docrunner и т. д.? -> если да, игнорируй это
мы можем получить действительный результат здесь?
если нет: проверьте стек и, возможно, получите оттуда результат
если стек также не дает действительного результата, тогда выдается исключение.
тем путем, мое решение работает до сих пор с setup.py test, uwsgi, pytest, pycharm pytest, pycharm docrunner (doctest), dreampie,eclipse
есть также хорошая статья в блоге об этой проблеме от Dough Hellman, "Определение имени процесса из Python"
Exception NameError: NameError("global name '__file__' is not defined",)
"__file__
не определено в интерактивном переводчике, потому что это бессмысленно. Он устанавливается реализацией импорта, поэтому, если вы используете нестандартный механизм импорта, он также может быть не установлен.import os
это необходимо для работы. Я бы добавил это в ответ.import os
иimport os.path
полностью эквивалентны.Это будет печатать
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__
является текущим исполняемым файлом, как указано в официальной документации :С Python3.4 годом, на вопрос 18416 ,
__file__
всегда абсолютный путь, если в данный момент выполняет файл не является сценарием , который был выполнен непосредственно (не через переводчик с-m
параметром командной строки) , используя относительный путь.__main__.__file__
(требует импорта__main__
) просто обращается к вышеупомянутому__file__
атрибуту основного модуля , например, сценария, который был вызван из командной строки.sys.argv[0]
(требует импортаsys
) - это имя сценария, которое было вызвано из командной строки и может быть абсолютным путем, как подробно описано в официальной документации :Как упоминалось в другом ответе на этот вопрос , скрипты Python, которые были преобразованы в автономные исполняемые программы с помощью таких инструментов, как py2exe или PyInstaller, могут не отображать желаемый результат при использовании этого подхода (то есть
sys.argv[0]
будут содержать имя исполняемого файла, а не имя основного файла Python в этом исполняемом файле).Если ни одна из вышеупомянутых опций не работает, возможно, из-за нерегулярной операции импорта, модуль проверки может оказаться полезным. В частности, вызов
inspect.getfile(...)
oninspect.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__ :Обратите внимание, что это
__main__.__file__
работает в Python 2.7, но не в 3.2, поэтому используйте синтаксис import-as, как описано выше, чтобы сделать его переносимым.источник
rPython
пакет изR
языка. Это, должно быть, исключительный случай, с которым слишком трудно разобраться.__main__
изнутри, для использования при передаче переменных междуR
иpython
, поэтому было бы относительно легко установить его__main__.__file__
перед вызовом чего-либо еще, но я даже не уверен, что будет подходящим значением в этом случае.Вышеуказанные ответы хороши. Но я нашел этот метод более эффективным, используя приведенные выше результаты.
Это приводит к фактическому имени файла сценария, а не к пути.
источник
Для современных версий Python (3.4+),
Path(__file__).name
должно быть более идиоматичным. Кроме того,Path(__file__).stem
дает вам имя сценария без.py
расширения.источник
from pathlib import Path
сначала.pathlib
был введен в Python 3.4, поэтому он должен работать, начиная с Python 3.4.Попробуй это:
источник
Примечание. Если вы используете Python 3+, вам следует использовать вместо этого функцию print ()
Предполагая, что имя файла
foo.py
, приведенный ниже фрагментили
Что касается других расширений с большим количеством символов, например имя файла
foo.pypy
Если вы хотите извлечь из абсолютного пути
будет выводить
foo
источник
__file__
иsys.argv[0]
, см. Stackoverflow.com/questions/5851588/…Первым аргументом в sys будет текущее имя файла, так что это будет работать
источник
Если вы делаете необычный импорт (например, это файл опций), попробуйте:
Обратите внимание, что это вернет абсолютный путь к файлу.
источник
мы можем попробовать это, чтобы получить текущее имя скрипта без расширения.
источник
Так как ОП запросил имя текущего файла скрипта, я бы предпочел
источник
все эти ответы великолепны, но есть некоторые проблемы, которые вы можете не увидеть с первого взгляда.
давайте определим, что мы хотим - нам нужно имя сценария, который был выполнен, а не имя текущего модуля - поэтому
__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"
источник
Мое быстрое грязное решение:
источник
os.path
для разделения имен файловos.path.abspath(__file__)
даст вам абсолютный путь (такжеrelpath()
доступно).sys.argv[-1]
даст вам относительный путь.источник
Начиная с Python 3.5 вы можете просто:
Подробнее здесь: https://docs.python.org/3.5/library/pathlib.html#pathlib.PurePath.stem
Например, у меня есть файл в моем пользовательском каталоге, названный
test.py
так:запустив эти выводы:
источник