Как вы получаете имя программы с помощью argparse?
Я использую argparse
для анализа аргументов командной строки. Просматривая документацию для argparse
, я мог видеть только условие использования другого имени программы.
Я хочу иметь возможность использовать имя программы по умолчанию без импорта sys
. Насколько мне известно, в argparse
нет ничего, что вернет имя программы.
import argparse
parser = argparse.ArgumentParser()
args = parser.parse_args()
print(dir(args))
И вот вывод:
['__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_get_args', '_get_kwargs']
Есть ли другой способ получить имя программы без импорта модуля sys
?
Ответы
Ответ 1
ArgumentParser
У экземпляров есть атрибут prog
, который, как я думаю, вам нужен.
import argparse
parser = argparse.ArgumentParser()
print('parser.prog: {}'.format(parser.prog))
Я обнаружил это, читая исходный код модуля в Lib/argparse.py
- особенно глядя на class ArgumentParser
определение. Поскольку имя атрибута не начинается с символа подчеркивания, я предполагаю его общедоступным.
Обновление
Я вижу, что, по крайней мере, в настоящее время атрибут prog
экземпляра ArgumentParser
является (или был с момента запроса этого вопроса) документирован как в Документация Python 2 и Документация Python 3.
Итак, да, это определенно публично, и в обеих версиях, если он не указан как аргумент ключевого слова при создании ArgumentParser
, по умолчанию он равен prog = _os.path.basename(_sys.argv[0])
(где _os
и _sys
являются частными argparse
, которые соответствуют их несимвольным префиксным аналогам. Обратите внимание, что из-за использования os.basename()
это будет только имя файла script, а не полный путь к нему, который может (зависит от ОС) был в sys.argv[0]
.
Ответ 2
Конечно, правильный способ:
>>> import sys
>>> print sys.argv[0]
scripts/script.py
Но пусть на мгновение у вас есть веская причина, которая мешает вам import sys
, но позволяет вам import argparse
.
martineau проделал замечательную работу по обнаружению prog
, попробуйте:
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> print parser.prog
script.py
Как отмечено hpaulj, у этого имени есть только имя файла, а не полный путь, например sys.argv[0]
, потому что модуль argparse.py
использует prog = os.path.basename(sys.argv[0])
.
Но argparse
должен использовать sys
, поэтому он должен быть доступен в пространстве имен argparse
. Пусть это проверит:
>>> import argparse
>>> print argparse.__dict__
{ ..., '_sys': <module 'sys' (built-in)>, ... }
Вот оно! Попробуйте использовать _sys
:
>>> import argparse
>>> print argparse._sys.argv[0]
scripts/script.py
Вы используете sys
! Конечно, но я не импортировал его, только argparse
, вот в чем вопрос!
Конечно, это имеет ряд противопоказаний:
- Вам не следует использовать переменные с префиксом
_
или __
других пространств имен, они используются внутренне.
- Вы не должны полагаться на импорт других модулей, они могут измениться.
- Вы не должны полагаться на недокументированные api, они могут измениться.
TL;DR
Это было весело, но просто придерживайтесь import sys
, пока argparse
не выпустит api для доступа к sys.argv[0]
.